正确的Linq where子句

我在日常生活中写了相当多的linq,但大多是简单的陈述。 我注意到,在使用where子句的时候,有很多方法可以写出来,每个都有相同的结果,据我所知。 例如;

from x in Collection where x.Age == 10 where x.Name == "Fido" where x.Fat == true select x; 

至less就结果而言似乎相当于此:

 from x in Collection where x.Age == 10 && x.Name == "Fido" && x.Fat == true select x; 

那么除了语法,还有其他的区别吗? 如果是这样,什么是首选的风格,为什么?

第二个效率更高,因为它只有一个谓词来对照集合中的每个项目进行评估,因为第一个谓词首先对所有项目应用第一个谓词,结果(此处缩小)是用于第二个谓词等等。 结果逐步缩小,但仍涉及多次传球。

另外,链接(第一个方法)只有在和你的谓词AND的时候才会起作用。 像这样的x.Age == 10 || x.Fat == true 你的第一个方法x.Age == 10 || x.Fat == true将不起作用。

编辑:LINQ到对象不performance我如何预期它。 你可能会对我刚刚写到的这篇博文感兴趣。


它们在所谓的方面是不同的 – 第一个相当于:

 Collection.Where(x => x.Age == 10) .Where(x => x.Name == "Fido") .Where(x => x.Fat == true) 

后者相当于:

 Collection.Where(x => x.Age == 10 && x.Name == "Fido" && x.Fat == true) 

现在究竟有什么区别取决于被调用的Where的实现。 如果它是一个基于SQL的提供者,我希望这两者最终创build相同的SQL。 如果它在LINQ to Objects中,那么第二个将具有更less的间接级别(将只有两个迭代器,而不是四个)。 不pipe这些间接方式在速度上是否显着 ,都是另外一回事。

通常我会使用几个where子句,如果他们觉得他们代表显着不同的条件(例如,一个是做一个对象的一部分,一个是完全分开的)和一个where子句时,各种条件密切相关(例如特定值大于最小值且小于最大值)。 基本上,在任何轻微的性能差异之前,值得考虑可读性。

第一个将实施:

 Collection.Where(x => x.Age == 10) .Where(x => x.Name == "Fido") // applied to the result of the previous .Where(x => x.Fat == true) // applied to the result of the previous 

与简单得多(假设更快)相比:

 // all in one fell swoop Collection.Where(x => x.Age == 10 && x.Name == "Fido" && x.Fat == true) 

当我跑步

 from c in Customers where c.CustomerID == 1 where c.CustomerID == 2 where c.CustomerID == 3 select c 

 from c in Customers where c.CustomerID == 1 && c.CustomerID == 2 && c.CustomerID == 3 select c customer table in linqpad 

对我的客户表输出相同的SQL查询

 -- Region Parameters DECLARE @p0 Int = 1 DECLARE @p1 Int = 2 DECLARE @p2 Int = 3 -- EndRegion SELECT [t0].[CustomerID], [t0].[CustomerName] FROM [Customers] AS [t0] WHERE ([t0].[CustomerID] = @p0) AND ([t0].[CustomerID] = @p1) AND ([t0].[CustomerID] = @p2) 

所以在翻译到SQL没有区别,你已经在其他答案中看到他们将如何转换为lambdaexpression式

仔细看,这两个语句将被转换成不同的查询表示。 根据CollectionQueryProvider ,这可能会被优化或不。

当这是一个linq-to-object调用时,多个where子句将导致一系列IEnumerables彼此读取。 使用单语句forms将有助于performance。

当底层提供者将其翻译成SQL语句时,两种变体都会创build相同的语句。