使用 SQL Compact/EF4 的 GUID 或 int 实体键?

Posted

技术标签:

【中文标题】使用 SQL Compact/EF4 的 GUID 或 int 实体键?【英文标题】:GUID or int entity key with SQL Compact/EF4? 【发布时间】:2010-03-20 18:20:40 【问题描述】:

这是我在使用 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() 方法来设置ID 属性,然后再将新实体添加到我的ObjectContext

这是我的问题:是否有一种简单的方法可以从 EF4 获取数据存储中的最后一个主键(无需为此创建第二个 ObjectContext)?还有什么理由不采取简单的方法并简单地使用 GUID?感谢您的帮助。

【问题讨论】:

您展示的方法看起来根本不是线程安全的!什么可以阻止两个线程获得相同的 ID? 对我来说不是问题——我只将 SQL CE 用于单用户应用程序,并且只在单线程上生成记录。不过,如果有人想在 SQL CE 中创建多线程记录,这点很好。 【参考方案1】:

我最终选择了 GUID。

大小/性能问题不是 对 SQL Compact 至关重要(甚至引人注目),因为 它是一个本地的单用户系统。 这不像应用程序将是 管理航空公司预订 系统。

至少在这一点上,有 似乎没有办法绕过“不 服务器生成的密钥”的限制 SQL Compact/EF4 堆栈。如果有人有聪明的 hack,我仍然愿意接受。

这并不意味着我会在 SQL Server 或 SQL Express 中采用相同的方法。我仍然对整数键有明确的偏好,SQL Compact 的较大兄弟允许它们与 EF4 结合使用。

【讨论】:

【参考方案2】:

使用指南。带有实体框架的 Compact Framework 不支持 AutoIncrement。

此外,如果您想创建一个使用多个数据源的应用程序,那么 int PK 将会非常非常快地分崩离析。

使用 Guid,您只需调用 Guid.NewGuid() 即可获取新密钥。 使用 int,您必须访问数据库才能获得有效的密钥。

如果将数据存储在多个数据库中,int PK会导致冲突。

【讨论】:

【参考方案3】:

我之前为 SQL CE 所做的,假设我们有一个访问数据库的应用程序,是在启动时计算 MAX 值并将其放入静态变量中。您现在可以轻松地分发顺序值,并且可以非常轻松地使生成它们的代码成为线程安全的。

【讨论】:

我实际上考虑过这种方法,这是一种很好的方法。我最终选择了 GUID,因为它很简单。【参考方案4】:

避免使用 Guid 的一个原因是大小 = 内存和存储空间消耗。

您还可以像这样查询 SQL Compact 元数据:

从 INFORMATION_SCHEMA.COLUMNS 中选择 AUTOINC_NEXT WHERE TABLE_NAME = 'Categories' AND AUTOINC_NEXT 不为 NULL

【讨论】:

如何使用 EF4 执行该查询?

以上是关于使用 SQL Compact/EF4 的 GUID 或 int 实体键?的主要内容,如果未能解决你的问题,请参考以下文章

SQL GUID 与整数

sql 获取当前插入的主键 表主键是guid类型的

将 GUID 与 SQL Server 和 NHibernate 一起使用

SQL GUID和自增列做主键的优缺点

sql如何将新产生的guid和一条其他表的数据插入当前表

sql SQL Guid,DateTime,Timestamp