【问题标题】:Why does the Entity Framework's DbContext.Find() generate a query with select top 2?为什么实体框架的 DbContext.Find() 会生成带有 select top 2 的查询?
【发布时间】:2011-10-19 14:29:00
【问题描述】:

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

【问题讨论】:

  • 我今天被这个观察吓坏了:)很高兴你已经发布了这个:P

标签: .net sql entity-framework-4.1


【解决方案1】:

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

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

真的只是一个假设。大概只有 EF 开发团队才能回答到底是什么原因。

编辑

如果我如上所述执行此操作(将列添加到 DB 中的复合键并在第一个键列中添加具有相同值的记录)然后调用 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

【讨论】:

  • 当我通过 LinqPad 和 VS 运行 SingleOrDefault 时,我从来没有得到 SELECT TOP 2。你从哪里得到的?这是 EF 特有的吗?
  • @JamieRRytlewski:EF 就是这种情况,是的。我不确定它是否是 EF 独有的。你测试了什么?使用 LINQ to SQL?
  • 是的,我使用的是 Linq to Sql....所以它一定是有区别的。我正在阅读,似乎它只出现在 EF 中。有TOP2是有道理的,我只是没见过,因为我不使用EF。
  • 这就是我的结论。确保它是独一无二的,但不要带回整个厨房水槽。所以“TOP 2”是有道理的,但我是 OP 的,你看到它看起来很奇怪。
猜你喜欢
  • 2020-05-13
  • 1970-01-01
  • 2012-10-26
  • 2011-09-02
  • 1970-01-01
  • 2013-10-27
  • 2022-01-22
  • 1970-01-01
  • 2012-03-09
相关资源
最近更新 更多