2009-09-14 115 views
2

我使用標準訪問者模式來遍歷LINQ表達式樹,以便生成動態SQL WHERE子句。如何評估LINQ表達式樹中的獨立布爾表達式

我的問題是,不像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 

當然是最後一個例子是作風不好,但我的代碼被設計成獨立工作的程序員的技能水平,所以不應付多餘的場景會對我而言,表現形式很差。

回答

5

以下情況是非常直截了當:

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

這些BinaryExpression節點,你可以直接將其轉化爲:

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

,你需要處理的特殊情況(S)是:

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

這些在表示方式中表示不同n樹(作爲MemberExpression)。因此,您需要特殊情況下的MemberExpression並確定它是否訪問布爾屬性。如果是的話,你把它翻譯成規範形式(在第二個例子中檢測UnaryExpression):

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

或者,你也許可以預先處理表達式樹和任何特殊情況下,轉化成它們的規範(表達樹)形式。例如,符合標準的任何MemberExpression節點都可以轉換爲正確的BinaryExpression

+0

嗨 我想達到同樣的效果。你能幫我理解嗎?例如,如果在一個表達式中,我有兩個不同的布爾表達式x => x.IsBool || x.IsBool == tue。如果我訪問他們的MemberExpressions,我得到這個代碼'WHERE IsBool = 1或IsBool = 1 =',這顯然已被破壞。如何區分一個元素表達式和另一個元素是否明確? – DolceVita 2016-06-09 22:08:36

0

在揭露操作員之前是否無法完全處理操作數?

即, EVAL每個:

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

WHERE (Enabled = 1) 

,然後在運營商包括在拉姆達的情況下,過程與等效的SQL渲染操作數的集合,以滿足運營商的需求。