[英]Proper Linq where clauses
我在日常生活中写了相当数量的linq,但大多是简单的陈述。 我注意到在使用where子句时,有很多方法可以编写它们,并且每个方法都有相同的结果。 例如;
from x in Collection
where x.Age == 10
where x.Name == "Fido"
where x.Fat == true
select x;
至少就结果而言,似乎与此相当:
from x in Collection
where x.Age == 10 &&
x.Name == "Fido" &&
x.Fat == true
select x;
那么语法之外真的有区别吗? 如果是这样,首选的风格是什么?为什么?
编辑:LINQ to Objects没有表现出我的预期。 您可能对我刚刚撰写的有关此内容的博文感兴趣...
它们在所谓的方面有所不同 - 第一个相当于:
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的提供程序,我希望这两个最终创建相同的SQL。 如果它在LINQ to Objects中,则第二个将具有较少的间接级别(仅涉及两个迭代器而不是四个)。 这些间接水平在速度方面是否重要是另一回事。
通常我会使用几个where
子句,如果他们觉得它们代表了显着不同的条件(例如,一个与一个对象的一部分有关,一个是完全独立的)和一个where
子句,当各种条件密切相关时(例如a特定值大于最小值且小于最大值。 基本上,在任何轻微的性能差异之前,值得考虑可读性。
第二个会更高效,因为它只有一个谓词来评估集合中的每个项目,如第一个,它首先将第一个谓词应用于所有项目,结果(此时缩小)是用于第二个谓词,依此类推。 结果每次通过都会缩小,但仍然需要多次通过。
此外,链接(第一种方法)仅在您对谓词进行AND运算时才有效。 像这样的东西x.Age == 10 || x.Fat == true
x.Age == 10 || x.Fat == true
将不适用于您的第一种方法。
第一个将实施:
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
对我的Customer表,它输出相同的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时没有区别,你已经在其他答案中看到它们将如何转换为lambda表达式
在引擎盖下,两个语句将转换为不同的查询表示。 根据Collection
的QueryProvider
,可能会优化或不优化。
当这是一个linq-to-object调用时,多个where子句将导致一组IEnumerables相互读取。 使用单子句形式将有助于提高性能。
当底层提供程序将其转换为SQL语句时,两个变体将创建相同语句的可能性很大。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.