为什么LINQ to objects方法的顺序很重要

gdo*_*ica 10 .net c# linq performance

我读了这个问题的答案,解释了LINQ to objects方法的顺序有所不同.我的问题是为什么?

如果我编写LINQ to SQL查询,那么LINQ方法的顺序无关紧要 - projections例如:

session.Query<Person>().OrderBy(x => x.Id)
                       .Where(x => x.Name == "gdoron")
                       .ToList();
Run Code Online (Sandbox Code Playgroud)

表达式树将转换为合理的SQL,如下所示:

  SELECT   * 
  FROM     Persons
  WHERE    Name = 'gdoron'
  ORDER BY Id; 
Run Code Online (Sandbox Code Playgroud)

当我运行查询时,无论方法的顺序多么奇怪,SQL查询都会根据表达式树构建.
为什么它不起作用LINQ to objects
当我枚举一个IQueryable时,所有的投影都可以放在一个合理的顺序中(例如,在Where之后的Order By)就像数据库优化器那样.

Ree*_*sey 14

为什么LINQ对象不能以这种方式工作?

LINQ to Objects不使用表达式树.该语句直接转换为一系列方法调用,每个方法调用都作为普通的C#方法运行.

因此,LINQ to Objects中的以下内容:

   var results = collection.OrderBy(x => x.Id)
                   .Where(x => x.Name == "gdoron")
                   .ToList();
Run Code Online (Sandbox Code Playgroud)

变成直接方法调用:

   var results = Enumerable.ToList(
                   Enumerable.Where(
                     Enumerable.OrderBy(collection, x => x.Id),
                     x => x.Name = "gdoron"
                   )
                 );
Run Code Online (Sandbox Code Playgroud)

通过查看方法调用,您可以看到为什么排序很重要.在这种情况下,通过首先放置OrderBy,您可以有效地将其嵌套到最内部的方法调用中.这意味着在枚举resutls时将订购整个集合.如果您要切换订单:

   var results = collection
                   .Where(x => x.Name == "gdoron")
                   .OrderBy(x => x.Id)
                   .ToList();
Run Code Online (Sandbox Code Playgroud)

然后生成的方法链切换到:

   var results = Enumerable.ToList(
                   Enumerable.OrderBy(
                     Enumerable.Where(collection, x => x.Name = "gdoron"),
                     x => x.Id
                   )
                 );
Run Code Online (Sandbox Code Playgroud)

反过来,这意味着只有过滤后的结果才需要在OrderBy执行时进行排序.


Ada*_*kis 8

Linq to objects的延迟执行与linq-to-sql(和EF)的工作方式不同.

使用linq-to-objects,方法链将按照列出方法的顺序执行 - 它不使用表达式树来存储和翻译整个事物.

OrderBy 然后 Where使用linq-to-objects 调用,当您枚举结果时,将对集合进行排序,然后对其进行过滤.相反,Where 使用OrderBywill 进行排序之前,通过调用过滤结果,当您枚举时,首先过滤,然后排序.因此,后一种情况可能会产生巨大的差异,因为您可能会对更少的项目进行排序.