将Linq Expression转换为具有给定属性值的字符串

时间:2016-05-23 21:10:47

标签: c# linq lambda

我想将linq Expression(Expression \\>)编译成字符串。

这很好用:

Expression<Func<MyTestClass, bool>> q5 = x => x.Prop1 == "abc" || x.Prop2 == 123;

通过调用q5.Body.ToString()得到预期的输出:

  

((x.Prop1 ==“abc”)OrElse(x.Prop2 == 123))

但是当我用更复杂的值替换任何BinaryExpression的右边部分时,问题就开始了。例如:

    var item = new MyTestClass {Prop2 = 123};
        var prop2 = 23;
        string prop = "abc";

        Expression<Func<MyTestClass, bool>> q5 = x => x.Prop1 == prop || x.Prop2 == item.Prop2;

输出变为:

  

((x.Prop1 == value(Tests.LambdaTests +&lt;&gt; c__DisplayClass0_0).prop)OrElse(x.Prop2 == value(Tests.LambdaTests +&lt;&gt; c__DisplayClass0_0).item.Prop2))

我或多或少地理解为什么Expression会编译成这个并且我可能需要通过查找MemberExpression类型并评估成员值来遍历所有表达式部分,但是这是一种更简单的方法来获得类似于第一个示例中的类似内容? 我需要的是用它的值替换'value(Tests.LambdaTests +&lt;&gt; c__DisplayClass0_0).item.Prop2)'。

谢谢

1 个答案:

答案 0 :(得分:0)

没有。 item是引用类型,必须在运行时解析。如果您稍后设置item.Prop2 = 456该怎么办?编译器不知道何时将评估q5,所以如果你要运行

Expression<Func<MyTestClass, bool>> q5 = x => x.Prop1 == prop || x.Prop2 == item.Prop2;
Console.WriteLine(q5.Body);
item.Prop2 = 456;
Console.WriteLine(q5.Body);

你会得到两个相同的

  

((x.Prop1 == value(Tests.LambdaTests +&lt;&gt; c__DisplayClass0).prop)OrElse(x.Prop2 =   = value(Tests.LambdaTests +&lt;&gt; c__DisplayClass0).item.Prop2))

通过在lambda中保留值类型,编译器知道它不会发生变化,并且无论何时进行评估,它都将始终检查"abc"123