When using LINQ, what is the difference between && and multiple where clauses?
The marked answer gets it a little bit inaccurate.
As @Philippe said, the first one will be translated into:
objectList.Where(o => o.value1 < 100).Where(o=> o.value2 > 10)
while the second one will be translated in:
objectList.Where(o => o.value1 < 100 && o.value2 > 10)
But Linq
has a little optimization for chained Where
calls.
If you inspect Linq's
source code you will see the following:
class WhereEnumerableIterator<TSource> : Iterator<TSource>
{
public override IEnumerable<TSource> Where(Func<TSource, bool> predicate)
{
return new WhereEnumerableIterator<TSource>(source,
CombinePredicates(this.predicate, predicate));
}
}
What CombinePredicates
does is is combining the two predicates with &&
between them:
static Func<TSource, bool> CombinePredicates<TSource>(Func<TSource, bool> predicate1,
Func<TSource, bool> predicate2)
{
return x => predicate1(x) && predicate2(x);
}
So objectList.Where(X).Where(Y)
is equivalent to objectList.Where(X && Y)
except for the creation time of the query (Which is extremely short anyway) and the invocation of two predicates.
Bottom line is that it does not filter or iterate the collection two times - but one composite time.
I've just profile it. No difference in SQL code
The first one will be translated into:
objectList.Where(o => o.value1 < 100).Where(o=> o.value2 > 10)
while the second one will be translated in:
objectList.Where(o => o.value1 < 100 && o.value2 > 10)
So, in the first one, you will have a first filtered sequence that is filtered again (first sequence contains all the objects with value < 100, the second one containing all the objects with value > 10 from the first sequence), in while the second one you will do the same comparisons in the same labda expression. This is valid fro Linq to objects, for other providers it depends how the expression is translated.
The first one translates to:
objectList.Where(o => o.value1 < 100)
.Where(o => o.value2 > 10);
while the latter gets you:
objectList.Where(o => o.value1 < 100 && o.value2 > 10);
It's functionally the same, and while the second one would spare a method call, the difference in performance is negligible. Use what's more readable for you.
That is, if you're using LINQ to Objects. If you're using a provider, it depends on how it's implemented (if the predicate is not factored in the resulting query, the result can be sub-optimal).