The value of a member expression may be accessed.

c# expression-trees lambda linq

Question

If a product is available.

var p = new Product { Price = 30 };

and I have the linq query shown below.

var q = repo.Products().Where(x=>x.Price == p.Price).ToList()

I get a MemberExpression from an IQueryable provider for the p.Price that has a Constant Expression, but I am unable to retrieve the value "30" from it.

Update This is what I attempted, 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.

2
67
4/11/2010 12:10:10 PM

Accepted Answer

A lambda expression whose body is the member access may be compiled and called:

private object GetValue(MemberExpression member)
{
    var objectMember = Expression.Convert(member, typeof(object));

    var getterLambda = Expression.Lambda<Func<object>>(objectMember);

    var getter = getterLambda.Compile();

    return getter();
}

When parsing expression trees, a typical approach is local evaluation. This is exactly what LINQ to SQL does in a number of areas.

109
8/22/2010 10:16:32 PM

Expert Answer

The capture-class that the constant expression will refer to is one that the compiler created. Here's how to subtract 30 from it if I've left out the decision points and other factors:

var p = new Product { Price = 30 };
Expression<Func<Product, bool>> predicate = x => x.Price == p.Price;
BinaryExpression eq = (BinaryExpression)predicate.Body;
MemberExpression productToPrice = (MemberExpression)eq.Right;
MemberExpression captureToProduct = (MemberExpression)productToPrice.Expression;
ConstantExpression captureConst = (ConstantExpression)captureToProduct.Expression;
object product = ((FieldInfo)captureToProduct.Member).GetValue(captureConst.Value);
object price = ((PropertyInfo)productToPrice.Member).GetValue(product, null);

price is now30 . Please note that I'm assumingPrice is a property, but you would really write aGetValue way for dealing with a field or property.

24
4/11/2010 12:17:35 PM


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow