手动为x => x.Child == itemToCompare.Child构建linq表达式

Han*_*man 1 linq lambda expression-trees

我们有一个对象,我们想要动态地基于该对象构建一个linq查询.这个linq语句等同于我们想要构建的内容:

Expression<Func<Sample, bool>> linqExpression 
            = x => x.Child == itemToCompare.Child;
Run Code Online (Sandbox Code Playgroud)

我们无法提出构建itemToCompare.Child部分的正确表达式.这是我们到目前为止所拥有的:

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);
Run Code Online (Sandbox Code Playgroud)

我们手工构建的查询的表达式树如下所示:

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
Run Code Online (Sandbox Code Playgroud)

实际lambda的表达式树看起来像:

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
Run Code Online (Sandbox Code Playgroud)

编辑:

我们认为这是有效的

Expression<Func<Sample, bool>> linqExpression 
            = x => x.Child == (()=>itemToCompare).Child;
Run Code Online (Sandbox Code Playgroud)

这就是我们在表达中试图重现的东西.

最终目标是生成一个Expression,使用Type的.Equals()方法比较Child值.

谢谢!

Joe*_*ari 12

你对"内在的lambda"感到困惑.只有一个lambda表达式:

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);
Run Code Online (Sandbox Code Playgroud)

  • 您可以通过将body表达式替换为以下来调用Equals:Expression.Call(typeof(object).GetMethod("Equals",BindingFlags.Static | BindingFlags.Public),lhs,rhs) (2认同)