代码之家  ›  专栏  ›  技术社区  ›  Handcraftsman

为x=>x手动生成linq表达式。child==itemtocompare.child

  •  1
  • Handcraftsman  · 技术社区  · 14 年前

    我们有一个对象,我们希望基于该对象即时构建一个LINQ查询。此LINQ语句等价于我们要生成的内容:

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

    我们无法找到正确的表达式来构建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);
    

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

    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
    

    实际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
    

    编辑:

    我们认为这是为了

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

    这就是我们试图在表达中重现的。

    最终的目标是生成一个表达式,在其中使用其类型的.equals()方法比较子值。

    谢谢!

    1 回复  |  直到 14 年前
        1
  •  12
  •   Joe Albahari    14 年前

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