SQL 文字列を生成するライブラリを VB.NET で作成しています。WHERE
ただし、句(および同様の構造)を生成すると、問題が発生します。最も単純なwhere句の構造は本質的に
expression1 [AND expression2 [AND expressionN]]
これは、オブジェクトのリストを使用してコードで簡単に表現できます。プログラムは、それぞれをループし、オーバーライドされたメソッドをExpression
呼び出して、毎回追加する必要があります (最後を除く)。単純。を考慮すると複雑になります。 where 句の構造は次のようになります。ToString()
AND
OR
expression1 [[AND|OR] expression2 [[AND|OR] expressionN]]
AND
すべての式を保持できるだけでなく、それぞれがorによって次の式から分離されているかどうかを追跡できるようにする必要があります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)