Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does LINQ-to-Entites recognize my custom method?

This works:

Entities.WorkOrderSet.Where(MyCustomMethod);

This does not:

Entities.WorkOrderSet.Where(o => MyCustomMethod(o));

([Edit] Even without new, it doesn't work)

I understand why the second doesn't work - but why in the world does the first work!? Shouldn't I get a "LINQ-to-Entities does not recognize the method..." at runtime, like with the second?

For reference, here is MyCustomMethod

public bool MyCustomMethod(WorkOrder workOrder)
{
    return !workOrder.WorkOrderNum.StartsWith("A", StringComparison.CurrentCultureIgnoreCase);
}

Using EF1, not EF4

like image 219
BlueRaja - Danny Pflughoeft Avatar asked Apr 20 '10 13:04

BlueRaja - Danny Pflughoeft


1 Answers

First works because it is an extension method and is is executing the query as a func, and then filtering your list see here. So in general it would automatically cast the where to

 Where(Func<WorkOrder, bool>

Second doesn't because it is pushing your where statement down to the db. When the lambda expression is evaluated it is expanded like this:

Where( Expresion<Func<WorkOrder, bool>>)

Here is a good article that explains Expressions vs Func

Here is another SO post that helps to explain the difference

[Edit (BlueRaja)]

This new edit appears to be correct. To clarify: it seems Func<WorkOrder, bool> is implicitly castable to Expression<Func<WorkOrder, bool>>, but not the other way around.

There are overloads of Where for both types. .Where(MyCustomMethod) is calling the Func<WorkOrder, bool> one, whereas .Where(o => MyCustomMethod(o)) is calling the Expression<Func<WorkOrder, bool>> one.

like image 131
Nix Avatar answered Oct 02 '22 20:10

Nix