这是我使用SQL Compact在EF4实体键上发布的earlier question的后续文章。SQL Compact不允许服务器生成的身份密钥,因此当对象被添加到ObjectContext时,我只能创建自己的密钥。我的第一个选择是整数键,前面的答案链接到一个blog post,其中显示了一个扩展方法,该方法使用带有选择器表达式的Max运算符来查找下一个可用的键:
public static TResult NextId<TSource, TResult>(this ObjectSet<TSource> table, Expression<Func<TSource, TResult>> selector)
where TSource : class
{
TResult lastId = table.Any() ? table.Max(selector) : default(TResult);
if (lastId is int)
{
lastId = (TResult)(object)(((int)(object)lastId) + 1);
}
return lastId;
}下面是我对扩展方法的看法:如果我正在使用的ObjectContext有一个未过滤的实体集,它将工作得很好。在这种情况下,ObjectContext将包含数据表中的所有行,我将获得准确的结果。但是,如果实体集是查询过滤器的结果,则该方法将返回过滤后的实体集中的最后一个实体键,而不一定是数据表中的最后一个键。所以我认为扩展方法不会真正起作用。
在这一点上,显而易见的解决方案似乎是简单地使用GUID作为实体键。这样,在向ObjectContext添加新实体之前,我只需要调用Guid.NewGuid()方法来设置ID属性。
我的问题是:有没有一种简单的方法可以从EF4获取数据存储中的最后一个主键(而不必为此创建第二个ObjectContext )?还有没有其他原因不选择简单的方法,直接使用GUID呢?谢谢你的帮助。
发布于 2010-03-22 20:05:50
我最终选择了GUID。
对于
这并不意味着我会在SQL Server或SQL Express中采用相同的方法。我仍然对整数键有明确的偏好,SQL Compact的更大的兄弟允许它们与EF4结合使用。
发布于 2010-03-26 13:41:52
使用Guid。具有实体框架的压缩框架不支持AutoIncrement。
此外,如果你想创建一个使用多个数据源的应用程序,int PK很快就会崩溃。
如果您将数据存储在多个数据库中,int PK会导致冲突。
发布于 2010-03-26 14:12:06
我以前对SQL CE所做的工作(假设我们只有一个应用程序访问数据库)是在启动时计算最大值并将其放入静态变量。现在,您可以轻松地分发序列值,并且可以非常轻松地使代码生成它们的线程安全。
https://stackoverflow.com/questions/2484192
复制相似问题