tags:

views:

92

answers:

3

Exactly how LINQ's "where" method is defined? I'm guessing implementation is something like this:

public static 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.

A: 

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)

Andrew Barber
+2  A: 

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);
Fredrik Mörk
+1  A: 

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.

Jon Hanna