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

Nat*_*ley 2 c# linq lambda expression-trees

我正在使用标准访问者模式迭代LINQ表达式树以生成动态SQL WHERE子句.

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

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

h => h.Enabled || h.Enabled == false
Run Code Online (Sandbox Code Playgroud)

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

WHERE Enabled OR Enabled = 0
Run Code Online (Sandbox Code Playgroud)

或者这段代码:

WHERE (Enabled = 1) OR (Enabled = 1) = 0
Run Code Online (Sandbox Code Playgroud)

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

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

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

h => h.Enabled
h => h.Enabled == enabled
h => h.Enabled == true
Run Code Online (Sandbox Code Playgroud)

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

Bra*_*non 5

以下案例非常简单:

h => h.Enabled == enabled
h => h.Enabled == true
Run Code Online (Sandbox Code Playgroud)

这些是BinaryExpression节点,您可以直接将它们转换为:

WHERE (Enabled = @p0)
WHERE (Enabled = 1)
Run Code Online (Sandbox Code Playgroud)

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

h => h.Enabled
h => !h.Enabled
Run Code Online (Sandbox Code Playgroud)

这些在表达式树中表示不同(作为a MemberExpression).所以你需要特殊情况MemberExpression并确定它是否正在访问一个布尔属性.如果是,则将其转换为规范形式(UnaryExpression在第二个示例中检测):

WHERE (Enabled = 1)
WHERE (Enabled = 0)
Run Code Online (Sandbox Code Playgroud)

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