我在VB.NET中創建一個用於生成SQL字符串的庫。然而,生成WHERE
子句(以及類似的結構)給了我一個問題。我已經確定了最簡單的where子句結構基本上是由可變分隔符分隔的一系列對象的類設計/模式
expression1 [AND expression2 [AND expressionN]]
這是很容易的代碼來表示與Expression
對象的列表 - 程序然後就必須通過每個循環中,調用其重寫ToString()
方法和追加AND
每次(除了最後一個)。簡單。併發症來當OR
考慮:一個where子句的結構變得
expression1 [[AND|OR] expression2 [[AND|OR] expressionN]]
我現在需要能夠既容納所有的表情,也是防不勝防是否每次從旁邊通過AND
或分離OR
- 本質的(expr1, andOr1, expr2, andOr2, ... exprN, andOrN)
的集合,我還認爲,結構可以嵌套過多,如:
(expression1 [[AND|OR] expression2]) [AND|OR] (expression3 [[AND|OR] expression4])
其中每個廿四括號內的一半本身就是一種表達方式。因此,我認爲該解決方案涉及通過擴展Expression
類進一步,使得表達可以是表達式的鏈:我有一個新的類ExpressionFromChainOfExpressions
:
Public Class ExpressionFromChainOfExpressions
Inherits Expression
Private ExprChain As List(Of Expression)
Public Sub AddExpression(Expr As Expression)
If ExprChain Is Nothing Then ExprChain = New List(Of Expression)
ExprChain.Add(Expression)
End Sub
Public Overrides Function ToString() As String
Dim outStr As String = "("
For i = 0 To ExprChain.Count - 1
outStr &= Expr.ToString()
If i < ExprChain.Count - 1
'ToDo: Determine [AND|OR] and append
'OLD: outStr &= " AND "
End If
Next
Return outStr & ")"
End Function
End Class
捆綁的And
/Or
作爲布爾標誌或一些這樣的進入Expression
類感覺錯 - 了Expression
應該是可重複使用的其他地方(他們也是在其他情況下,如case when expression [[and|or] expression] ...
突然出現,並And
/Or
本身不是表達式的一部分
不要緊,能否解決。是3線收藏伎倆或一個全新的家庭。可維護性和可擴展性非常重要 - 它不能被破解。如果有人知道解決這類問題的設計模式,我很樂意看到它。
編輯:按照要求,只是使用And
(從實際的代碼大大簡化由於真實運動部件的數量)的一些示例代碼:
Public MustInherit Class Expression
Public MustOverride Function ToString() As String
End Class
Public Class ExpressionFromString
Inherits Expression
Private ExprString As String
Public Sub New(ExprString As String)
Me.ExprString = ExprString
End Sub
Public Overrides Function ToString() As String
Return ExprString
End Function
End Class
Public Class ExpressionFromChainOfExpressions
Inherits Expression
Private ExprChain As List(Of Expression)
Public Sub AddExpression(Expr As Expression)
If ExprChain Is Nothing Then ExprChain = New List(Of Expression)
ExprChain.Add(Expression)
End Sub
Public Overrides Function ToString() As String
Dim outStr As String = "("
For i = 0 To ExprChain.Count - 1
outStr &= Expr.ToString()
If i < ExprChain.Count - 1
outStr &= " AND "
End If
Next
Return outStr & ")"
End Function
End Class
主要方法:
Public Module Module1
Dim myExpr1 = New ExpressionFromString("A = B")
Dim myExpr2 = New ExpressionFromString("C > 100")
dIM myExpr3 = New ExpressionFromString("D Is Null")
Dim myNestedChain = New ExpressionFromChainOfExpressions()
myExprChain.Add(myExpr1)
myExprChain.Add(myExpr2)
Console.WriteLine("WHERE " & myNestedChain.ToString())
Dim myOuterChain = New ExpressionFromChainOfExpressions()
myOuterChain.Add(myNestedChain)
myOuterChain.Add(myExpr3)
Console.WriteLine("WHERE " & myOuterChain.ToString())
End Module
輸出:
WHERE (A = B AND C > 100)
WHERE ((A = B AND C > 100) AND D Is Null)
我不完全確定你想要完成什麼;但是您知道And/Or(和AndAlso等替代方法)是ExpressionType枚舉的一部分(http://msdn.microsoft.com/zh-cn/library/bb361179.aspx),不是嗎? – varocarbas
是的,謝謝,我知道。爲了澄清,'And' /'Or'這裏只是一個輸出字符串,它需要存儲在某個地方並用於鏈表達式(程序不會使用它們來運行條件檢查本身)。對於所有的程序而言,它可能是'Bananas' /'Waffles' - 問題是我需要一些方法來定義一個鏈,鏈中的每個鏈接都由'And'或'Or'(或'Bananas'或Waffles'):) – Kai
你能寫一個實際的例子給你的類的輸入(ExpressionFromChainOfExpressions變量是...)和ToString重載函數的預期輸出(當執行.ToString()時我想得到...)?這肯定有助於澄清你想要的東西。 – varocarbas