sql-server - OrderBy().FirstOrDefault(<条件>) 与Where(<条件>).OrderBy().FirstOrDefault()

标签 sql-server linq-to-sql entity-framework-6

我在 C# 项目中使用 EntityFramework 6.1.3 和 SQL Server。 我有两个查询,基本上应该执行相同的操作。

1.

Exams.GroupBy(x=>x.SubjectID).Select(x => x.OrderBy(y => y.Level.NumericValue).FirstOrDefault(y => y.Date.Value > DateTime.Today))

2.

Exams.GroupBy(x=>x.SubjectID).Select(x => x.Where(y => y.Date.Value > DateTime.Today).OrderBy(y => y.Level.NumericValue).FirstOrDefault())

但是,第一个查询的结果与我将订单留在一边的结果相同。 第二个按预期工作。

当我通过 Linqpad 查看生成的 SQL 时,第一个查询中没有 order by 子句。

我的问题是,为什么第一个查询不像第二个查询那样工作? 我一直以为

.Where(<condition>).FirstOrDefault() == .FirstOrDefault(<condition>)

就像已经在这里回答的那样:.Where(<condition>).FirstOrDefault() vs .FirstOrDefault(<condition>)

编辑: 我又进行了一些尝试,发现这两个查询产生相同的 SQL 输出。

Exams.GroupBy(x => x.SubjectID).Select(x => x.FirstOrDefault(y => y.Date.Value > DateTime.Today))
Exams.GroupBy(x => x.SubjectID).Select(x => x.OrderBy(y => y.Level.NumericValue).FirstOrDefault(y => y.Date.Value > DateTime.Today))

尽管它看起来像一个错误,但我仍然没有 100% 相信。

最佳答案

尽管 related bug report已关闭,因为在此回答,这显然是一个错误。我在 GroupBy 中使用类似的 OrderByDescending 结构,后跟带有谓词的 FirstOrDefault 结构,遇到了完全相同的问题。

Entity Framework 似乎不支持带有谓词的 FirstOrDefault 语句,至少在本问题的上下文中不支持。正如问题所述,以下表达式会生成带有 ORDER BY 子句的正确 SQL 查询:

Exams
    .GroupBy(x => x.SubjectID)
    .Select(x => x
        .Where(y => y.Date.Value > DateTime.Today)
        .OrderBy(y => y.Level.NumericValue)
        .FirstOrDefault())

但是,向 FirstOrDefault 语句添加任何谓词都会使 EF 感到困惑,并导致查询不带 ORDER BY :

Exams
    .GroupBy(x => x.SubjectID)
    .Select(x => x
        .Where(y => y.Date.Value > DateTime.Today)
        .OrderBy(y => y.Level.NumericValue)
        .FirstOrDefault(y => true)) // Tautology shouldn't have any effect, but it does!

解决此问题的唯一方法是将 FirstOrDefault(predicate) 语句拆分为 Where(predicate).FirstOrDefault()。只需确保在代码中添加注释来解释此决定,因为 ReSharper 正确地建议使用单个 FirstOrDefault(predicate) 语句。但这样做会让你的查询出错!

关于sql-server - OrderBy().FirstOrDefault(<条件>) 与Where(<条件>).OrderBy().FirstOrDefault(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31162938/

相关文章:

sql - 使用 SQL 检测连续日期范围

c# - SQL Server 中 varchar(MAX) 的大小限制

c# - 为什么这个 Linq 代码总是抛出 System.StackOverflowException?

c# - 如何使用递归编程填充包含多个类别的列表框

javascript - AngularJS 中的数组未获取字符串值

c# - 手动添加迁移?

c# - SavingChanges 事件与 SaveChanges 覆盖之间的区别?

sql - 性能 - Int vs Char(3)

php - 将 mySQL 数据库的日志文件日期时间格式从 12 小时制批量转换为 24 小时制

c# - SQL Server - Guid VS。长