如何从Expression<Func<T, bool>>谓词中获取属性、运算符和值?

7

有没有办法从 Expression<Func<T>,bool> 中提取属性、运算符和匹配值?给出以下示例:

var customers = GetCustomers();
var customerQuery = customers.Where(x=> x.CustomerID == 1 
    && x.CustomerName == "Bob"); // The query is for illustration only

我需要能够输出以下类似的内容:
Property: CustomerID
Operator: Equals
Value:    1

Property: CustomerName
Operator: Equals
Value:    Bob

我已经编写了一些代码,可以提取表达式中的属性名,但是似乎无法找到值和运算符存储在哪里,尽管在表达式的DebugView属性中非常明显可见。

2个回答

8
运算符将位于BinaryExpressionMethod,即Equals节点。你还应该查看表达式.NodeType,它可以揭示很多信息(应该是Equal)。
通常情况下,将在那个BinaryExpression.Right中的ConstantExpression中,或者在捕获变量的情况下: 捕获上下文将是ConstantExpression,因此将是一个MemberExpression,其基于ConstantExpression(您需要调查成员是FieldInfo还是PropertyInfo,并通过.GetValue(...)获取该值)。

太好了,谢谢。只需要使用(BinaryExpression)predicate.Bodypredicate进行转换,现在一切都很明显了。感谢Marc。 - djdd87

3
除了Marc Gravells的回答外(+1),我想补充一点,值得一提的是看看ExpressionVisitor类(在.Net 4中已经预设好,在MSDN上有一个示例可以复制/粘贴到3.5版本中)。它使得编写代码来提取某些类型的表达式变得非常容易。
在你的情况下,你将要覆盖它的VisitBinary方法。
我通常使用这个类将我感兴趣的表达式推入只读列表中,例如,然后我会在类的实现中公开它。你不会用它来重写表达式。

+1,谢谢。这确实使查找二进制表达式变得更容易了,但我仍然会接受Marc的答案,因为它说明了如何提取我需要的信息。 - djdd87
是的,我同意 - Marc的答案为您提供了这个问题的要点,值得采纳;我的回答只是提供了一种简单的方法来实现他所建议的 :) - Andras Zoltan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接