小编典典

为什么实体框架的DbContext.Find()会生成一个带有选择顶部2的查询?

sql

为什么实体框架的DbContext.Find()会生成带有选择顶部2和派生表的查询?根据定义,查询是通过主键查找的,该键应该是唯一的。


阅读 147

收藏
2021-03-23

共1个答案

小编典典

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

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

真的只是一个假设。只有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

2021-03-23