2010-12-16 41 views
11

想知道,添加LINQ方法的顺序是否重要?任何重要的LINQ方法的顺序?

例如,

using(MyDataContext context = new MyDataContext()) 
{ 
    var user = context.Users 
        .Where(u => u.UserName.StartsWith("t")) 
        .OrderByDescending(u => u.CreatedDate) 
        .FirstOrDefault(); 
} 

,这完全是一样的吗?

using(MyDataContext context = new MyDataContext()) 
{ 
    var user = context.Users 
        .OrderByDescending(u => u.CreatedDate) 
        .Where(u => u.UserName.StartsWith("t")) 
        .FirstOrDefault(); 
} 

当然,我可以让所有的方法一个一个地测试,但我想对逻辑有一些总体的想法。

所以:

  • 除了像FirstOrDefault(),ToList()等方法方法,真正触发执行是它的任何重要的是具有在LINQ声明某种类型的订单?

再次感谢!

+0

在这种情况下,我只是比较生成的查询并手动在数据库上执行它们以进一步分析执行计划。 – 2010-12-16 08:36:27

回答

10

在LINQ to SQL中,我期望这两个查询是相同的 - 即使不是完全相同的SQL,它们也应该以相同的查询计划结束。

在LINQ to Objects中,它们的行为会非常不同。想象一下,你有一百万用户,但其中只有两个用户名以“t”开头。在第一种形式中,您需要过滤然后对这两个用户进行排序......在第二种形式中,它需要在开始过滤之前对的所有内容进行排序

当然,还有其他情况下,订购也很重要 - 特别是,如果您有一个Select一半,然后Where子句,那么您将过滤不同的事情。想象一下:

var query = Enumerable.Range(-20, 30) 
         .Select(x => -x) 
         .Where(x => x > 5); 

VS

var query = Enumerable.Range(-20, 30) 
         .Where(x => x > 5) 
         .Select(x => -x); 

在第一示例中的结果将是 “20,19,18,... 6”,而在所述第二查询的结果将是“-6 ,-7,-8,-9,-10“。巨大的不同!

1

我不是100%确定的,但我认为第二个比较慢,因为您对一大组数据进行排序。如果您首先进行过滤,则会删除一些元素,从而使分类更快。但是,结果应该是一样的。

编辑:由于这看起来像linq-to-sql(如果您不使用另一个linq提供程序),它应该归结为在此示例中执行的相同查询。但是有些情况下,linq-to-sql中的顺序也很重要(参见Jon的例子)。然而,唯一能够100%确定的方法是使用分析器来调查生成的sql查询(但在这个例子中我不认为有任何区别)。

+0

@Tomas:这是从LINQ到SQL,看起来它......我希望* *客户端查询生成*或*服务器端优化器发现。 – 2010-12-16 08:36:39

+0

@Jon:这是真的,对于LINQ到SQL,他们应该生成相同的SQL。我只考虑了linq部分,并没有反映'DataContext'。这件事情是你不能确定,或者你可以吗?唯一的方法是使用分析器来真正检查生成的sql查询。 – 2010-12-16 08:41:33

+0

@Tomas:在这种情况下我相当有信心 - 但我认为这是一个好主意,看看你的LINQ产生什么类型的查询:) – 2010-12-16 08:43:09

0

它可能有性能问题。在你的情况下,第一个例子将是最好的,因为在第二个例子中,你首先在过滤之前对整个列表进行排序。你甚至可以将所有不需要的东西分类,然后删除不需要的部分。首先删除所有你不需要的东西,然后你将排序(可能)要小得多的子集。

所以对于这个确切的查询,结果是一样的,但是对于一组大数据,第一个数据将是最快的一个。

+0

@Øyvind:根据我对其他答案的评论:这看起来像LINQ to SQL,其执行流程几乎没有LINQ to Objects那样规定。我希望即使在大量数据上,它们也能够等效执行 - 因为SQL查询优化器应该对它进行排序。 – 2010-12-16 08:38:11

+0

@Jon - 在回顾这个问题时,我同意你的看法,这看起来像LINQ to SQL,当然你是对的。然而,在LINQ to Objects上,差异将是至关重要的。 – 2010-12-16 08:52:09

1

一般来说,是的,它确实很重要。你可以得到不同的表现和/或不同的结果。

在您的具体示例中,订单不会改变结果。对于大多数提供程序(如LINQ to SQL和LINQ to Entities),它们也不会有任何区别 - 将生成相同的SQL。

对于其他提供者,不同的顺序可能会改变性能特征,但它如何确实取决于特定的提供者。例如,我不认为LINQ to Objects对于两个查询都会有相同的性能。

1

如何使用Sql Profiler?那会给出正确的答案。

4

这取决于您正在使用哪个LINQ提供程序。在LINQ to SQL的情况下,无论哪种情况,表达式树都将解析为相同的基础SQL查询。但是,对于不太聪明的提供者,您可能会发现先执行.Where()会更有效,因为它会在对它们进行排序之前过滤对象,这可能会对大量实体产生不同影响。

1

我认为这是关于LINQ到XXXX的提供者。谁写的提供者可以说它可以做什么(关于优化等)。即使在同一个LINQ提供者的另一个版本中,也可能给出不同的结果(只是在翻译中)。

简而言之,LINQ提供者只是翻译者,所以你应该从现在使用的LINQ提供者的创建者那里提出这个问题。