How does LINQ's "Where" method works?
Exactly how LINQ's "where" method is defined? I'm guessing implementation is something like this:
public static开发者_JS百科 IEnumerable<T> Where ( this partialParent, Func<bla,bla> myDelegate )
Now if I invoke Where method like this:
from c in context.Con
where ( c.Col1 == c.Col2 )
select c
I'm guessing "c.Col1 == c.Col2"
is passed down and some foreach
loop does the checking. But what is going on when I invoke where like this:
where ( c.Col1 == c.Col2 || c.Col3 == c.Col4 )
Does the two "checks" are passed down as a whole expression? Maybe I'm missing something very simple.
In the case of linq-to-objects, you can consider it to be the equivalent of enumeration.Where(c => c.Col1 == c.Col2)
or enuemration.Where(c => c.Col1 == c.Col2 || c.Col3 == c.Col4)
.
The easiest way to implement Where
would be something like:
public static IEnumerable<T> Where<T>(this IEnumerable<T> src, Func<T, bool> pred)
{
foreach(T item in src)
if(pred(item))
yield return item;
}
Though if you look at the code in reflector you'll see a lot of optimisations on this basic idea.
However, it this call to Where
is just one way that where
could implemented. Because LINQ queries can be executed against lots of different queryable sources, there are other possibilities. It could for example be turned into a SQL WHERE
clause on a query sent to the database. It can be informative to execute some queries using Linq2SQL, and run a SQL Profiler and look at what is sent to the server.
The following "pseudo"-code blocks give the same code:
// first
from item in sequence
where expression
select item;
// second
sequence.Where(item => expression);
It does not matter how many comparisons that are made in expression as long as it yields a boolean result. It's still one expression.
This means that the following two are also identical:
// first
from c in context.Con
where ( c.Col1 == c.Col2 || c.Col3 == c.Col4 )
select c;
// second
context.Con.Where(c => c.Col1 == c.Col2 || c.Col3 == c.Col4);
The query syntax you mention for where
basically creates a method and delegate, and calls the method syntax version with it. Whatever you call where
with is turned into a single method and then called via a delegate on each element of the source sequence.
So possibly what you mean by the two checks being passed as a whole expression; that's what is happening...
where ( c.Col1 == c.Col2 || c.Col3 == c.Col4 )
it turned into a single method call like this:
bool MethodExample(var c){
return ( c.Col1 == c.Col2 || c.Col3 == c.Col4 );
}
and is then called on each element. (obviously the above is pseudo-code)
精彩评论