开发者

Partial Evaluation of ConstantExpression in ExpressionTreeVisitor

I am not an Expression Tree master by any stretch of the imagination, what I have is code that looks like this:

    int external = 10;
    using(var session = new Session())
    {
       session.Add(new Product { Name = "test1", Price = 20 });
       session.Add(new Product {Name = "test", Price = 10});
       var product = session.Products.Where(p => p.Price == external).FirstOrDefault();
       Assert.Equal(10, product.Price);
    }

Session implements all the IQueryProvider, IQueryable interfaces you'd come to expect from a LINQ Provider.

When I evaluate the expression tree, everything goes to plan until I read the ConstantExpression for "external", at whi开发者_JAVA技巧ch point, I am at a loss as to how to move forward because:

      //constant is ConstantExpression for "external" on the right side of the "p.Price == external" expression above.
      var t = constant.GetType(); //evaluates to class called "<>c__DisplayClass2" - with a member named "external" that has the value 10. 

The question is basically.. How can I just access the value of the member "external" - is there a way to accomplish this without using reflection? or am I cooked? What am I missing?


Your expression captures the external local variable, that's why an anonymous type is implicitly created by the compiler to wrap the captured variable. The right-hand side part of the equality is not a ConstantExpression, it's actually a MemberExpression, whose Expression property is a ConstantExpression of type <>c__DisplayClass2

You can access the value of the property as follows :

MemberExpression memberExpr = /* right-hand side of the equality */ as MemberExpression;
ConstantExpression constantExpr = memberExpr.Expression as ConstantExpression;
PropertyInfo prop = memberExpr.Member as PropertyInfo;
object value = prop.GetValue(constantExpr.Value, null);


I prefer something like this. It is more general and will work for a number of cases.

var operation = (BinaryExpression)predicate.Body;
var righthandValue= Expression.Lambda(operation.Right).Compile().DynamicInvoke();
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜