为什么Entity Framework DbContext.Find()使用select top 2生成查询?

时间:2011-10-19 14:29:01

标签: .net sql entity-framework-4.1

为什么Entity Framework的DbContext.Find()使用select top 2和派生表生成查询?根据定义,查询是通过主键查找的,主键应该是唯一的。

1 个答案:

答案 0 :(得分:18)

Find首先检查具有给定键的实体是否已在上下文中。如果没有,它会查询数据库。在这种情况下,它可能使用SingleOrDefault的LINQ查询。如果结果包含多个实体,SingleOrDefault会转换为SELECT TOP 2以便能够抛出异常。

那么,为什么不Find使用FirstOrDefault(这会转换为SELECT TOP 1)。我不知道,但我猜想Find想要检查该实体在数据库中是否真的是唯一的。它应该 - 因为它是查询使用的主键 - 但是模型和数据库可能不同步,因为有人更改了数据库中的主键,例如:向数据库中的复合键添加了列,但未在模型中添加。

真的只是一个假设。只有EF开发团队可能会回答原因。

修改

如果我按上述方法执行此操作(在DB中添加列复合键并在第一个键列中添加具有相同值的记录)然后调用Find,我会得到例外...

  

序列包含多个元素

...和这个stacktrace:

//...
System.Linq.Queryable.SingleOrDefault[TSource](IQueryable`1 source)
System.Data.Entity.Internal.Linq.InternalSet`1.FindInStore(
    WrappedEntityKey key, String keyValuesParamName)
System.Data.Entity.Internal.Linq.InternalSet`1.Find(Object[] keyValues)
System.Data.Entity.DbSet`1.Find(Object[] keyValues)

因此,Find确实使用了SingleOrDefault