繁体   English   中英

正确的Linq条款

[英]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表达式

在引擎盖下,两个语句将转换为不同的查询表示。 根据CollectionQueryProvider ,可能会优化或不优化。

当这是一个linq-to-object调用时,多个where子句将导致一组IEnumerables相互读取。 使用单子句形式将有助于提高性能。

当底层提供程序将其转换为SQL语句时,两个变体将创建相同语句的可能性很大。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM