2010-10-22 39 views
1

我们有一个对象,我们希望基于该对象即时创建一个linq查询。此LINQ语句相当于我们所要建设:手动为x => x.Child创建linq表达式。== itemToCompare.Child

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 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()方法比较Child值。

谢谢!

回答

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

Joe,它将Child属性的值视为一个常量。当该值是引用类型时,它似乎执行引用比较而不是调用.Equals()。我们需要它调用.Equals()。 – Handcraftsman 2010-10-25 14:41:25

+2

您可以通过替换正文表达式来调用Equals:Expression.Call(typeof(object).GetMethod(“Equals”,BindingFlags.Static | BindingFlags.Public),lhs,rhs) – 2010-10-26 03:52:26