这是我使用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作为实体密钥。这样,我只需要在我向Guid.NewGuid()
添加新实体之前调用ObjectContext
方法来设置ID属性。
以下是我的问题:是否有一种简单的方法可以从EF4获取数据存储中的最后一个主键(无需为此目的创建第二个ObjectContext
)?任何其他理由不采取简单的方法,只是使用GUID?谢谢你的帮助。
答案 0 :(得分:3)
我最终选择了GUID。
尺寸/性能问题不是 SQL Compact的关键(甚至是引人注目),因为 它是一个本地的单用户系统。 它不像应用程序那样 管理航空公司预订 系统。
至少在这一点上,那里 似乎没有办法绕过“不 服务器生成的密钥“的限制 SQL Compact / EF4堆栈。如果有人有一个聪明的黑客,我仍然愿意接受它。
这并不意味着我会在SQL Server或SQL Express中采用相同的方法。我仍然对整数键有一定的偏好,而SQL Compact的更大的兄弟姐妹允许它们与EF4一起使用。
答案 1 :(得分:1)
使用Guid。具有实体框架的Compact Framework不支持AutoIncrement。
此外,如果你想创建一个使用多个数据源的应用程序,那么你将非常非常快速地解决这个问题。
如果将数据存储在多个数据库中,则int PK将导致冲突。
答案 2 :(得分:1)
我以前为SQL CE所做的事情,我假设我们有一个访问数据库的应用程序,就是在启动时计算MAX值并将其放在一个静态变量中。您现在可以轻松地分发顺序值,并且可以使代码非常容易地生成线程安全。
答案 3 :(得分:0)
避免Guids的一个原因是size =内存和存储空间消耗。
您还可以像这样查询SQL Compact元数据:
从INFORMATION_SCHEMA.COLUMNS中选择AUTOINC_NEXT WHERE TABLE_NAME ='Categories'且AUTOINC_NEXT不为空