Sometimes developers don’t know whether they should use a Func<> or an Expression<Func<>> with the Entity Framework and LINQ.
The difference may be critical in same situations.
Let’s say that you have a metod that perform a query with a where condition made as this:
public IEnumerable<MyEntity> LoadMyEntities(string parameter)
{
return Context.MyEntities.Where(x=>x.sameValue==parameter);
}
If you have to use the same method but with different where condition to be applied you can decide to refactor using a predicate.
The refactor should be:
public IEnumerable<MyEntity> LoadMyEntities(Func<MyEntity, bool> predicate)
{
return Context.MyEntities.Where(predicate);
}
Here you are doing something really dangerous!
What are you doing is to query the entite table and then apply the filter by the predicate.
Why?
The answer is in the way that the framework manages extension methods.
The reason this makes a difference is that a predicate that’s in the form of an Expression is passed to SQL server, but a predicate that’s passed as a Func is not.
Using a Func, the where that extends IEnumerable is used.
The Entity Framework’s fluent interface for constructing SQL queries is based on IQueryables, not IEnumerables, so the fluency stops just before the Where.
The final result is that all the table is loaded!
The entire table is now filtered with the predicate, and the value we really want is returned.
So let’s use Expression.
public IEnumerable<MyEntity> LoadMyEntities(Expression<Func<MyEntity, bool> >predicate)
{
return Context.MyEntities.Where(predicate);
}
In this case the compiler uses the Where that extends IQueryable.
The predicate is thus passed to SQL Server, which dutifully returns just one row to the context.