使用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
版本。