首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OrderBy().FirstOrDefault(<condition>)与Where(<condition>).OrderBy().FirstOrDefault()

OrderBy().FirstOrDefault(<condition>)与Where(<condition>).OrderBy().FirstOrDefault()
EN

Stack Overflow用户
提问于 2015-07-01 13:34:44
回答 5查看 7.4K关注 0票数 8

我在一个EntitiyFramework项目中与Server一起使用C# 6.1.3。我有两个问题,基本上应该这样做。

1.

代码语言:javascript
复制
Exams.GroupBy(x=>x.SubjectID).Select(x => x.OrderBy(y => y.Level.NumericValue).FirstOrDefault(y => y.Date.Value > DateTime.Today))

2.

代码语言:javascript
复制
Exams.GroupBy(x=>x.SubjectID).Select(x => x.Where(y => y.Date.Value > DateTime.Today).OrderBy(y => y.Level.NumericValue).FirstOrDefault())

但是,第一个查询的结果与我将离开订单的结果相同。第二种方法如预期的那样工作。

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

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

代码语言:javascript
复制
.Where(<condition>).FirstOrDefault() == .FirstOrDefault(<condition>)

就像这里已经回答过的:)

编辑:,我再多玩一遍,我发现这两个查询产生了相同的输出。

代码语言:javascript
复制
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))

尽管它看起来像个bug,但我仍然不能百分之百地相信。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2015-07-02 16:04:36

不确定这是否是问题的根本原因,但这两个查询之间有细微的区别-- OrderBy的相对位置和位置。在关系世界中,过滤器无效排序在子查询中完成。EF试图通过在过滤器后“提升”一些命令来弥补这一差异,并且可能无法正确地提升此模式。尝试在第二个查询中切换OrderBy和位置:

代码语言:javascript
复制
Exams.GroupBy(x => x.SubjectID).Select(x => x.OrderBy(y => y.Level.NumericValue).Where(y => y.Date.Value > DateTime.Today).FirstOrDefault())

并查看是否仍然获得与未更改版本相同的生成SQL。如果是这样的话,它肯定是EF中的一个bug (我希望生成的sql与查询1相同,并且与原始查询2不同)。否则,可能只是提升算法对阶数的限制。

一般来说,如果你想让EF更容易,最好把你的OrderBy放在你的Where-s之后。

票数 1
EN

Stack Overflow用户

发布于 2015-10-13 13:56:31

尽管相关错误报告在这里被关闭,但这显然是一个错误。我遇到了一个完全相同的问题,使用了类似的OrderByDescending结构,后面跟着FirstOrDefault和谓词,在GroupBy中。

实体框架似乎不支持带有谓词FirstOrDefault 语句,至少在这个问题的上下文中不支持。正如问题所述,以下表达式使用ORDER BY子句生成一个正确的SQL查询:

代码语言:javascript
复制
Exams
    .GroupBy(x => x.SubjectID)
    .Select(x => x
        .Where(y => y.Date.Value > DateTime.Today)
        .OrderBy(y => y.Level.NumericValue)
        .FirstOrDefault())

但是,向ORDER BY语句添加任何谓词都会混淆EF并导致没有的查询。

代码语言:javascript
复制
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)语句。但是这样做会使您的查询陷入麻烦!

票数 3
EN

Stack Overflow用户

发布于 2015-07-01 17:23:03

这个问题的答案取决于LINQ提供程序,这里是EF。LINQ提供程序支持的特定模式很少有完整的文档记录。我不知道任何EF文件在这个问题上。目前还不清楚这是否是一个bug,或者它是否应该工作。

LINQ技术本身无法保证这将始终有效。

我认为这应该是可行的,或者至少是非常理想的,它的工作。创建一个指向此问题的简短Github问题。这支队伍反应迅速。

目前,你别无选择,只能选择有效的模式。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31162938

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档