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

发布于 2024-08-26 10:18:16 字数 1246 浏览 5 评论 0原文

这是我在使用 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 吗?感谢您的帮助。

This is a follow-up to an earlier question I posted on EF4 entity keys with SQL Compact. SQL Compact doesn't allow server-generated identity keys, so I am left with creating my own keys as objects are added to the ObjectContext. My first choice would be an integer key, and the previous answer linked to a blog post that shows an extension method that uses the Max operator with a selector expression to find the next available key:

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;
}

Here's my take on the extension method: It will work fine if the ObjectContext that I am working with has an unfiltered entity set. In that case, the ObjectContext will contain all rows from the data table, and I will get an accurate result. But if the entity set is the result of a query filter, the method will return the last entity key in the filtered entity set, which will not necessarily be the last key in the data table. So I think the extension method won't really work.

At this point, the obvious solution seems to be to simply use a GUID as the entity key. That way, I only need to call Guid.NewGuid() method to set the ID property before I add a new entity to my ObjectContext.

Here is my question: Is there a simple way of getting the last primary key in the data store from EF4 (without having to create a second ObjectContext for that purpose)? Any other reason not to take the easy way out and simply use a GUID? Thanks for your help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

身边 2024-09-02 10:18:17

我最终选择了 GUID。

  • 尺寸/性能问题不是
    对于 SQL Compact 至关重要(甚至是值得注意),因为
    它是一个本地单用户系统。
    这不像应用程序那样
    管理航班预订
    系统。

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

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

I ended up going with a GUID.

  • The size/performance issues aren't
    critical (or even noticeable) with SQL Compact, since
    it is a local, single-user system.
    It's not like the app will be
    managing an airline reservation
    system.

  • And at least at this point, there
    seems to be no way around the "no
    server-generated keys" limitation of
    the SQL Compact/EF4 stack. If someone has a clever hack, I'm still open to it.

That doesn't mean I would take the same approach in SQL Server or SQL Express. I still have a definite preference for integer keys, and SQL Compact's bigger siblings allow them in conjunction with EF4.

追风人 2024-09-02 10:18:17

使用指南。带有 Entity Framework 的 Compact Framework 不支持自动增量。

另外,如果您想创建一个使用多个数据源的应用程序,int PK 很快就会让您崩溃。

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

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

Use a Guid. AutoIncrement is not supported on Compact Framework with Entity Framework.

Also, if you ever want to create a application which uses multiple data sources, int PK's are going to fall apart on you very, very quickly.

  • With Guid's, you can juse call Guid.NewGuid() to get a new key.
  • With int's, you have to hit the database to get a valid key.

If you store data in multiple databases, int PK's will cause conflicts.

爱人如己 2024-09-02 10:18:17

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

What I've done for SQL CE before, and I assume we have a single application accessing the database, is to calculate the MAX value on startup and put it in a static variable. You can now hand out sequential values easily and you can make the code to generate them thread safe very easily.

荆棘i 2024-09-02 10:18:17

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

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

SELECT AUTOINC_NEXT FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = '类别' AND AUTOINC_NEXT 不为空

One reason to avoid Guids would be size = memory and storage space consumption.

You could also query SQL Compact metadata like so:

SELECT AUTOINC_NEXT FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Categories' AND AUTOINC_NEXT IS NOT NULL

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文