SQL Compact/EF4 的 GUID 或 int 实体键?
这是我在使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我最终选择了 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.
使用指南。带有 Entity Framework 的 Compact Framework 不支持自动增量。
另外,如果您想创建一个使用多个数据源的应用程序,int PK 很快就会让您崩溃。
如果将数据存储在多个数据库中,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.
If you store data in multiple databases, int PK's will cause conflicts.
我之前对 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.
避免使用 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