我刚刚开始使用实体框架,所以我决定将它连接到我现有的SQL Server CE数据库。我有一个带有IDENTITY(1,1)主键的表,但是当我尝试添加实体时,我遇到了上述错误。
从MS Technet artice我学到了
与实体框架一起使用时,SQL Server Compact不支持具有服务器生成的密钥或值的实体。 使用实体框架时,实体的密钥可能会标记为服务器生成。这使数据库能够在插入或实体创建时为密钥生成值。另外,实体的零个或多个属性可以标记为服务器生成的值。有关更多信息,请参阅Entity Framework文档中的Store Generated Pattern主题。 虽然实体框架允许您使用服务器生成的键或值定义实体类型,但SQL Server Compact在与实体框架一起使用时不支持具有服务器生成的密钥或值的实体。对具有服务器生成的值的实体的数据操作操作会引发“不支持”异常。
所以现在我有几个问题:
答案 0 :(得分:24)
当我达到此限制时,我将类型更改为uniqueidentifier
答案 1 :(得分:17)
使用uniqueidentifier或手动生成bigint / int键值是最佳选择。
这样的事可能......
private static object lockObject = new object();
private static long nextID = -1;
public static long GetNextID()
{
lock (lockObject)
{
if (nextID == -1) nextID = DateTime.UtcNow.Ticks; else nextID++;
return nextID;
}
}
这假设您在应用程序运行期间每次打勾不会生成多个记录(加上停止和重新启动的时间)。我认为这是一个合理的假设,但是如果你想要一个完全防弹(但更复杂)的解决方案,那么从数据库中读取最高的ID并从中增加。
答案 2 :(得分:6)
SQL CE 4.0版通过其实体框架提供程序修复了此问题。
答案 3 :(得分:4)
我刚刚也遇到了这个问题...大多数人都认为这是最好的选择,GUID非常容易使用,而且密钥冲突的风险很低(尽管不是很难)。
- 如果不支持将密钥标记为服务器生成,为什么会抛出异常?从引用的段落中很难看出来。
因为SQL Server(非Compact)支持它,而其他第三方也可能支持它......实体框架不仅适用于SQL Server Compact;)
答案 4 :(得分:4)
就我而言,我的所有课程都有名为“ID”的主键
我创建了一个界面
public class IID
{
public Int32 ID { get; set; }
}
然后我创建了一个扩展方法
public static Int32 GetNextID<T>(this ObjectSet<T> objects)
where T : class, IID
{
T entry = objects.OrderByDescending(u => u.ID).FirstOrDefault();
if (entry == default(T))
return 1;
return entry.ID + 1;
}
然后,当我需要一个新ID时,我就这样做了:
MyObject myobj = new MyObject();
myobj.ID = entities.MyTable.GetNextID();
答案 5 :(得分:1)
另一个选项是在具有标识列的表上使用SqlCeResultSet。
答案 6 :(得分:0)
我有一个名为ID的主键,数据类型为INT32,并且具有标识列
就这样做
MyEntity Entity = new MyEntity();
字符串命令;
command =“Insert into Message(Created,Message,MsgType)值('12 / 1/2014','Hello World',5); Entity.ExecuteStoreCommand(命令);
- 排除插入语句
中的主键 - 由于SQLCE不支持系统生成的密钥
- 不要使用LINQ,因为它为具有a的主键提供默认值0 INT的数据类型