使用LINQ时,&&和多个where子句之间有什么区别?

我是LINQ的新手,昨天发现你可以有多个where子句,例如:

var items = from object in objectList where object.value1  10 select object; 

或者你可以写:

 var items = from object in objectList where object.value1  10 select object; 

两者有什么区别?

第一个将被翻译成:

 objectList.Where(o => o.value1 < 100).Where(o=> o.value2 > 10) 

而第二个将翻译成:

 objectList.Where(o => o.value1 < 100 && o.value2 > 10) 

因此,在第一个中,您将有一个第一个过滤的序列再次过滤(第一个序列包含值<100的所有对象,第二个序列包含第一个序列中值> 10的所有对象),而第二个你将在同一个labda表达式中进行相同的比较。 这对于Linq对象是有效的,对于其他提供者,它取决于表达式的翻译方式。

明确的答案让它有点不准确。

正如@Philippe所说,第一个将被翻译成:

 objectList.Where(o => o.value1 < 100).Where(o=> o.value2 > 10) 

而第二个将翻译成:

 objectList.Where(o => o.value1 < 100 && o.value2 > 10) 

Linq对链接的Where调用进行了一些优化。

如果您检查Linq's源代码,您将看到以下内容:

 class WhereEnumerableIterator : Iterator { public override IEnumerable Where(Func predicate) { return new WhereEnumerableIterator(source, CombinePredicates(this.predicate, predicate)); } } 

CombinePredicates所做的是将两个谓词与它们之间的&&组合在一起:

 static Func CombinePredicates(Func predicate1, Func predicate2) { return x => predicate1(x) && predicate2(x); } 

所以objectList.Where(X).Where(Y)等同于objectList.Where(X && Y)除了查询的创建时间(无论如何都非常短)和两个谓词的调用。

底线是它不会过滤或迭代集合两次 – 而是一个复合时间。

第一个转换为:

 objectList.Where(o => o.value1 < 100) .Where(o => o.value2 > 10); 

而后者得到你:

 objectList.Where(o => o.value1 < 100 && o.value2 > 10); 

它的function完全相同,虽然第二个会省去方法调用,但性能上的差异可以忽略不计。 使用对您而言更具可读性的内容。

也就是说,如果你使用linq来对象。 如果您正在使用提供程序,则取决于它的实现方式(如果在结果查询中未考虑谓词,则结果可能是次优的)。

我只是简介它。 SQL代码没有区别

在最基本的级别,您将获得两个Where操作而不是一个。 使用Reflector是检查查询表达式另一端出现的内容的最佳方法。

它们是否优化到同一个东西取决于实际的LINQ提供程序 – 它需要占用整个树并将其转换为另一种语法。 对于LINQ To Objects,它没有。

C#in Depth很适合让您了解这个主题。

对于答案来说如何:使用&&你不能保证两个表达式都要被评估(如果第一个条件为假,那么第二个条件可能不被评估)。 有了两个where子句,那么你就可以了。 不知道这是否属实,但对我来说听起来不错!

在所有其他condition1 && condition2相同的condition1 && condition2 ,为了代码可读性,我会选择condition1 && condition2版本。