正确的Linq条款

A.R*_*.R. 128 c# linq

我在日常生活中写了相当数量的linq,但大多是简单的陈述.我注意到在使用where子句时,有很多方法可以编写它们,并且每个方法都有相同的结果.例如;

from x in Collection
  where x.Age == 10
  where x.Name == "Fido"
  where x.Fat == true
  select x;
Run Code Online (Sandbox Code Playgroud)

至少就结果而言,似乎与此相当:

from x in Collection
  where x.Age == 10 &&
        x.Name == "Fido" &&
        x.Fat == true
  select x;
Run Code Online (Sandbox Code Playgroud)

那么语法之外真的有区别吗?如果是这样,首选的风格是什么?为什么?

Jon*_*eet 138

编辑:LINQ to Objects没有表现出我的预期.您可能对我刚刚撰写的有关此内容的博文感兴趣...


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

Collection.Where(x => x.Age == 10)
          .Where(x => x.Name == "Fido")
          .Where(x => x.Fat == true)
Run Code Online (Sandbox Code Playgroud)

后者相当于:

Collection.Where(x => x.Age == 10 && 
                      x.Name == "Fido" &&
                      x.Fat == true)
Run Code Online (Sandbox Code Playgroud)

现在实际上有什么区别取决于Where被调用的实现.如果它是一个基于SQL的提供程序,我希望这两个最终创建相同的SQL.如果它在LINQ to Objects中,则第二个将具有较少的间接级别(仅涉及两个迭代器而不是四个).这些间接水平在速度方面是否重要是另一回事.

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

  • @Asad:已更新.(我的博客已经移动了.) (2认同)

Bal*_*a R 74

第二个会更高效,因为它只有一个谓词来评估集合中的每个项目,如第一个,它首先将第一个谓词应用于所有项目,结果(此时缩小)是用于第二个谓词,依此类推.结果每次通过都会缩小,但仍然需要多次通过.

此外,链接(第一种方法)仅在您对谓词进行AND运算时才有效.这样的东西x.Age == 10 || x.Fat == true不能用你的第一种方法.

  • 使用此扩展可以在某种程度上实现链 ORing 条件:http://www.albahari.com/nutshell/predicatebuilder.aspx (2认同)

use*_*116 12

第一个将实施:

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
Run Code Online (Sandbox Code Playgroud)

而不是更简单(并且速度快得多):

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

  • "快得多"?我们甚至不知道涉及哪个LINQ实现,因此很难将任何性能影响附加到它上面. (6认同)
  • 确实......但你声称后者*的速度要快得多.它根本不是很明显*它会显着*更快 - 毕竟,性能差异的重要性将取决于它的使用方式. (2认同)

Muh*_*hid 11

当我跑

from c in Customers
where c.CustomerID == 1
where c.CustomerID == 2
where c.CustomerID == 3
select c
Run Code Online (Sandbox Code Playgroud)

from c in Customers
where c.CustomerID == 1 &&
c.CustomerID == 2 &&
c.CustomerID == 3
select c customer table in linqpad
Run Code Online (Sandbox Code Playgroud)

对我的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)
Run Code Online (Sandbox Code Playgroud)

所以在转换为sql时没有区别,你已经在其他答案中看到它们将如何转换为lambda表达式