1

这是我在使用 SQL Compact 的 EF4 实体键上发布的一个较早问题的后续内容。SQL Compact 不允许服务器生成的身份密钥,因此当对象添加到ObjectContext. 我的第一选择是整数键,上一个答案链接到博客文章,该文章显示了一种扩展方法,该方法使用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?谢谢你的帮助。

4

4 回答 4

3

我最终选择了 GUID。

  • SQL Compact 的大小/性能问题并不严重(甚至不明显),因为它是一个本地的单用户系统。该应用程序不会管理航空公司预订系统。

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

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

于 2010-03-22T12:05:49.957 回答
1

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

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

  • 使用 Guid,您可以直接调用 Guid.NewGuid() 来获取新密钥。
  • 使用 int,您必须访问数据库才能获得有效的密钥。

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

于 2010-03-26T05:41:51.827 回答
1

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

于 2010-03-26T06:12:05.933 回答
0

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

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

从 INFORMATION_SCHEMA.COLUMNS 中选择 AUTOINC_NEXT,其中 TABLE_NAME = 'Categories' 并且 AUTOINC_NEXT 不为空

于 2010-03-21T11:19:00.667 回答