如何评估LINQ表达式树中的独立布尔表达式

时间:2009-09-14 21:38:38

标签: c# linq lambda expression-trees

我正在使用标准访问者模式来遍历LINQ表达式树,以便生成动态SQL WHERE子句。

我的问题是,与C#不同,你不能在SQL中使用独立的布尔表达式;你必须将它与1或0进行比较。

鉴于这个假设的lambda表达式:

h => h.Enabled || h.Enabled == false

错误地生成此代码很容易:

WHERE Enabled OR Enabled = 0

或此代码:

WHERE (Enabled = 1) OR (Enabled = 1) = 0

当然两者都会产生SQL错误。我应该采用什么逻辑来解决这个问题,而我的代码开始变得非常迟钝,因为我深入研究子树以找出案例可能是什么?

编辑:上面的例子当然是多余的 - 我只是用它来说明一点。

可能会创建此方案的示例:

h => h.Enabled
h => h.Enabled == enabled
h => h.Enabled == true

当然,最后一个例子是糟糕的风格,但是我的代码被设计为独立于程序员的技能水平而工作,所以不能满足冗余场景将是我的不良形式。

2 个答案:

答案 0 :(得分:5)

以下案例非常简单:

h => h.Enabled == enabled
h => h.Enabled == true

这些是BinaryExpression个节点,您可以直接将它们翻译成:

WHERE (Enabled = @p0)
WHERE (Enabled = 1)

您需要处理的特殊情况是:

h => h.Enabled
h => !h.Enabled

在表达式树中以不同的方式表示它们(作为MemberExpression)。因此,您需要特殊情况MemberExpression并确定它是否正在访问布尔属性。如果是,则将其翻译为规范形式(在第二个示例中检测UnaryExpression):

WHERE (Enabled = 1)
WHERE (Enabled = 0)

或者,您可以预处理表达式树并将任何特殊情况转换为规范(表达式树)表单。例如,符合条件的任何MemberExpression节点都可以转换为正确的BinaryExpression

答案 1 :(得分:0)

在影响运算符之前,是否无法完全处理操作数?

IE中。评估每个:

h => h.Enabled
h => h.Enabled == enabled
h => h.Enabled == true

WHERE (Enabled = 1)

然后在lambda中包含运算符的情况下,使用等效的SQL处理渲染的操作数的集合,以满足运算符的要求。