【问题标题】:EF Behavior of Last and LastOrDefaultLast 和 LastOrDefault 的 EF 行为
【发布时间】:2021-12-07 15:29:35
【问题描述】:

最近我正在增强我对 EF 的了解,为了了解最新情况,我刚刚去了 Pluralsight 上的洞路径。考虑到这一点,我查看了 Julie Lerman 的几门课程,顺便说一句,这是一位很棒的老师。

在课程中,我们简要回顾了 linq 的一些内置功能以及它如何将其解释为查询。我只是想知道这是否会通过功能版本进行更新,并想知道为什么会这样。

来自 Entity Framework Core:入门课程引用:“最后一个方法要求查询按方法排序,否则将返回完整集,然后在内存中选择最后一个。”

谢谢

【问题讨论】:

    标签: entity-framework entity-framework-core entity-framework-6 entity-framework-5


    【解决方案1】:

    First/Last 方法都应该始终有一个 Order By 子句来尝试并确保结果是可重复的。在 EF linq 表达式中使用 Last 方法确实没有充分的理由,只需颠倒排序并使用 First 方法。唯一可能的原因是您需要查询表达式中的第一项和最后一项。

    您可以通过运行分析器并检查生成的 SQL 来了解很多关于 EF 正在做什么的信息。为什么 EF 需要 Order By 子句来执行 Last 操作,我想到了两个原因。首先是 SQL 通常会使用类似于 MAX(...) 表达式的东西来处理 LAST 类型的场景,这需要一列或多列才能计算出来。第二个是它可能会根据条件来扭转现有的秩序。我以为这是第一个选项,但查看生成的 SQL 实际上是第二个。

    var test = context.Parents.OrderBy(x => x.Name).First();
    
    SELECT TOP(1) [p].[ParentId], [p].[MasterParentId], [p].[Name]
    FROM [Parents] AS [p]
    ORDER BY [p].[Name] 
    go
    
    var test = context.Parents.OrderBy(x => x.Name).Last();
    
    SELECT TOP(1) [p].[ParentId], [p].[MasterParentId], [p].[Name]
    FROM [Parents] AS [p]
    ORDER BY [p].[Name] DESC
    go
    

    您可能与 SQL Server 一起使用的 MAX 方法可能取决于提供程序,并且在使用多个 Order By 表达式时可能会出现问题。

    值得注意的是,EF 支持 Linq 方法的能力是特定于提供程序实现的,因此并非所有提供程序或所有版本的 EF 都支持所有操作。例如,EF6 不支持 Last/LastOrDefault 方法,它们希望您反转 Order By 条件并使用 First*

    Last 方法需要 OrderBy 子句以避免在内存中执行操作的原因可能是 EF 会生成一个查询,该查询将值与 MAX(...) 操作进行比较。否则,它无法生成 SQL 语句来获取最后一行,并且必须加载所有内容以进行枚举。

    【讨论】:

    • 非常感谢。我还有一些其他问题已发布。可以帮助我解决 IHttpFactory 问题吗?另外有什么方法可以联系你咨询吗?
    猜你喜欢
    • 2023-03-13
    • 1970-01-01
    • 2021-07-24
    • 1970-01-01
    • 1970-01-01
    • 2020-01-02
    • 2013-10-18
    • 1970-01-01
    • 2012-08-27
    相关资源
    最近更新 更多