Access the value of a member expression

2019-01-12 23:05发布

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.

8条回答
老娘就宠你
2楼-- · 2019-01-13 00:03

Using Expression.Lambda(myParameterlessExpression).Compile().Invoke() has several drawbacks:

  • .Compile() is slow. It can take multiple milliseconds to complete even for small expression fragments. The Invoke-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 of Expressions 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 than Compile() - and avoid the memory leak!

查看更多
放荡不羁爱自由
3楼-- · 2019-01-13 00:06
 MemberExpression right = (MemberExpression)((BinaryExpression)p.Body).Right;
 Expression.Lambda(right).Compile().DynamicInvoke();
查看更多
登录 后发表回答