首页 > 解决方案 > C# Linq 查询执行顺序

问题描述

考虑以下方法:

public IEnumerable<Owner> GetOwners(OwnerParameters ownerParameters)
{
    return FindAll()
        .OrderBy(on => on.Name)
        .Skip((ownerParameters.PageNumber - 1) * ownerParameters.PageSize)
        .Take(ownerParameters.PageSize)
        .ToList();
}

哪里FindAll()是返回IQueryable<Owner>. 拥有.OrderBy()before.Skip().Take()方法是否意味着Owner数据表中的所有元素都将被检索和排序,或者,Linq 是否考虑到.Skip()and.Take()方法可能会缩小所需Owner元素的范围,并且只有在检索到这些元素之后才会发生排序?

编辑:探查器日志:

SELECT XXX
FROM [Owners] AS [a]
ORDER BY [a].[Name]
OFFSET @__p_0 ROWS FETCH NEXT @__p_1 ROWS ONLY',N'@__p_0 int,@__p_1 int',@__p_0=0,@__p_1=10

标签: c#linqentity-framework-core

解决方案


最终,这取决于做什么FindAll()以及它返回什么:

  • 如果它返回IEnumerable<T>,那么它正在使用 LINQ-to-Objects,它基本上只是按照字面意思执行;如果您对页面进行排序,则对页面进行排序;如果你分页然后排序,那么分页然后排序
  • 但是,如果它返回IQueryable<T>,则查询正在被组合- 并且仅在 中实际执行ToList(),此时提供程序模型有机会检查您的查询树并构建可能的最合适的实现,这通常意味着:编写一个 SQL 查询包括一个ORDER BY和一些适用于特定 RDBMS 的分页提示;如果您的代码分页然后排序(这是......不寻常),那么我希望大多数提供者要么编写某种可怕的子查询来尝试描述它,要么NotSupportedException只是厌恶地抛出异常(也许)

推荐阅读