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

喜夏-厌秋 提交于 2020-01-29 10:02:29

问题


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!


回答1:


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);


来源:https://stackoverflow.com/questions/4001082/manually-build-linq-expression-for-x-x-child-itemtocompare-child

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!