If i have a product.
var p = new Product { Price = 30 };
and i have the following linq query.
var q = repo.Products().Where(x=>x.Price == p.Price).ToList()
In an IQueryable provider, I get a MemberExpression back for the p.Price which contains a Constant Expression, however I can't seem to get the value "30" back from it.
Update I have tried this but it doesn't seem to work.
var memberExpression = (MemberExpression)GetRootConstantExpression(m);
var fi = (PropertyInfo)memberExpression.Member;
var val = fi.GetValue(((ConstantExpression)memberExpression.Expression).Value, null);
Cheers.
Using
Expression.Lambda(myParameterlessExpression).Compile().Invoke()
has several drawbacks:.Compile()
is slow. It can take multiple milliseconds to complete even for small expression fragments. TheInvoke
-call is super-fast afterwards though, takes only few nanoseconds for simple arithmetic expressions or member accesses..Compile()
will generate (emit) MSIL code. That might sound perfect (and explains the excellent execution speed) but the problem is: That code takes up memory, which can not be freed before the application finishes, even when the GC collected the delegate-reference!One can either avoid
Compile()
altogether to avoid these issues or cache the compiled delegates for re-using them. This little library of mine offers both interpretation ofExpressions
as well as cached compilation, where all constants and closures of the expression get replaced by additional parameters automatically, which are then re-inserted in a closure, which is returned to the user. Both processes are well-tested, used in production, both have their pros and cons against each other but are well over 100x faster thanCompile()
- and avoid the memory leak!