为什么实体框架的DbContext.Find()会生成带有选择顶部2和派生表的查询?根据定义,查询是通过主键查找的,该键应该是唯一的。
Find首先检查具有给定键的实体是否已在上下文中。如果不是,它将查询数据库。在这种情况下,它可能使用的LINQ查询SingleOrDefault。如果结果具有多个实体,则SingleOrDefault转换为SELECT TOP 2能够引发异常。
Find
SingleOrDefault
SELECT TOP 2
因此,为什么不Find使用FirstOrDefault(将转换为SELECT TOP 1)。我不知道,但我想我Find想检查一下该实体在数据库中是否确实是唯一的。它应该-因为它是查询使用的主键-但模型和数据库可能不同步,因为有人更改了数据库中的主键,例如:在数据库中而不是模型中的复合键中添加了一个列。
FirstOrDefault
SELECT TOP 1
真的只是一个假设。只有EF开发团队可能可以回答确切的原因。
编辑
如果我如上所述进行此操作(将列添加到数据库中的复合键,并在第一键列中添加具有相同值的记录)并调用then Find,则会得到异常…
序列包含多个元素
…以及此堆栈跟踪:
//... 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。