使用LINQ时,&&和和多个where子句?

时间:2009-10-30 09:11:00

标签: c# .net linq

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

var items = from object in objectList
where object.value1 < 100  
where object.value2 > 10  
select object;

或者你可以写:

var items = from object in objectList
where object.value1 < 100  
   && object.value2 > 10  
select object;

两者有什么区别?

7 个答案:

答案 0 :(得分:18)

第一个将被翻译成:

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

而第二个将翻译成:

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

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

答案 1 :(得分:10)

标记的答案有点不准确。

正如@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<TSource> : Iterator<TSource>
{
    public override IEnumerable<TSource> Where(Func<TSource, bool> predicate)
    {
        return new WhereEnumerableIterator<TSource>(source, 
            CombinePredicates(this.predicate, predicate));
    }
}

CombinePredicates的作用是将两个谓词与&&组合在一起:

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

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

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

答案 2 :(得分:6)

第一个转换为:

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

而后者得到你:

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

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

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

答案 3 :(得分:3)

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

答案 4 :(得分:1)

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

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

C# in Depth很高兴让您了解这个主题。

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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