manually build linq expression for x => x.Child == itemToCompare.Child

expression-trees lambda linq

Question

We have an object and we want to build a linq query based on that object on the fly. This linq statement is equivalent to what we want to build:

Expression<Func<Sample, bool>> linqExpression 
            = x => x.Child == itemToCompare.Child;

We can't quite come up with the right expression to build the itemToCompare.Child part. Here's what we have so far:

var param = Expression.Parameter(typeof(T), "x");
var key = itemToCompare.GetType().GetProperty("Child");
var rhsConstant = Expression.Constant(item);
var innerLambda = Expression.Lambda<Func<T>>(rhsConstant, 
            new ParameterExpression[0]);
var rhsMemberAccess = Expression.MakeMemberAccess(innerLambda, key);
body = Expression.Equal(lhsPropertyAccess, rhsMemberAccess);
var lambda = Expression.Lambda<Func<T, bool>>(body, param);

The expression tree for our hand-built query looks like:

Lambda Expression: x => (x.Child = value(SampleTests+Sample))
Expression Body: (x.Child = value(SampleTests+Sample))
Parameter 0: 'x', Type: Sample
NodeType: Lambda
   Left Lambda Expression: x.Child
   Left NodeType: MemberAccess
      Lambda Expression: x
      Expression Member: Sample Child
      NodeType: Parameter
         -- a parameter expression
   Right Lambda Expression: value(SampleTests+Sample)
   Right NodeType: Constant
      NodeType: Constant
      Value: SampleTests+Sample

The expression tree for the actual lambda looks like:

Lambda Expression: x => (x.Child = value(SampleTests+<>c__DisplayClass15).itemToCompare.Child)
Expression Body: (x.Child = value(SampleTests+<>c__DisplayClass15).itemToCompare.Child)
Parameter 0: 'x', Type: Sample
NodeType: Lambda
   Left Lambda Expression: x.Child
   Left NodeType: MemberAccess
      Lambda Expression: x
      Expression Member: Sample Child
      NodeType: Parameter
         -- a parameter expression
   Right Lambda Expression: value(SampleTests+<>c__DisplayClass15).itemToCompare.Child
   Right NodeType: MemberAccess
      Lambda Expression: value(SampleTests+<>c__DisplayClass15).itemToCompare
      Expression Member: Sample Child
      NodeType: MemberAccess
         Lambda Expression: value(SampleTests+<>c__DisplayClass15)
         Expression Member: Sample itemToCompare
         NodeType: Constant
            NodeType: Constant
            Value: SampleTests+<>c__DisplayClass15

Edit:

We think this works out to

Expression<Func<Sample, bool>> linqExpression 
            = x => x.Child == (()=>itemToCompare).Child;

which is what we're trying to reproduce in our expression.

Ultimately the goal is to produce an Expression where the Child values are compared using their Type's .Equals() method.

Thanks!

Accepted Answer

You're getting confused by the "inner lambda". There's only one lambda expression:

var param = Expression.Parameter(typeof(Sample), "x");
var key = itemToCompare.GetType().GetProperty("Child");
var rhs = Expression.MakeMemberAccess(Expression.Constant(itemToCompare), key);
var lhs = Expression.MakeMemberAccess(param, key);
var body = Expression.Equal(lhs, rhs);
var lambda = Expression.Lambda<Func<Sample, bool>>(body, param);



Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why