With entity framework, we can do :
MyContext context = ... // a normal EF context
var products = context.Products.Where(p => p.Location == "France") ;
or
var products = context.Products.Where(p => p.CategoryId == 54) ;
Which are both translate in their equivalent SQL query.
OK, but somewhere over there, there's a piece of code that handle this :
public static IEnumerable<T> Where(Func<bool, T> func) {
......
}
From that Where
function, how do LINQ to SQL
know what's the implementation of func
?
Obvious answer maybe, but I can't really find it.
You should really do a Go To Definition on your code. The function used for LINQ-to-SQL and for Entity Framework is
IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate)
contained in the System.Linq.Queryable that uses expression trees, that are a constuct able to "describe" pieces of code. A little quote:
Expression trees represent code in a tree-like data structure, where each node is an expression, for example, a method call or a binary operation such as x < y.
For example, your first expression
var products = context.Products.Where(p => p.Location == "France");
is converted by the C# compiler to this code:
ParameterExpression par = Expression.Parameter(typeof(Product), "p");
LambdaExpression lambda = Expression.Lambda(
Expression.Equal(
Expression.Property(par, "Location"),
Expression.Constant("France")),
par);
var products = context.Products.Where(lambda);
Now... while the creation of an expression tree is quite simple, the reverse operation (de-building an expression tree and creating a query) is something VERY VERY complex. Big big headache complex. Nearly magic-level complex :-)
The problem isn't de-building the expression tree. That is easy. You use an ExpressionVisitor and you are done. The problem is merging the various layers of LINQ query and comprehending what the programmer wanted to obtain.
I'll add that IL (the "assembly" of .NET) is high level enough that it is possible to decompile it (see for example IlSpy). There is at least a library, DelegateDecompiler that is able to decompile a delegate to an Expression Tree, so even without Expression Trees, LINQ-to-SQL and EF could have used something similar and decompiled methods directly to SQL language.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments