Vb.net 由变量分隔符分隔的对象链的类设计/模式

Vb.net 由变量分隔符分隔的对象链的类设计/模式,vb.net,Vb.net,我正在VB.NET中创建一个生成SQL字符串的库。然而,生成WHERE子句(以及类似的结构)给了我一个问题。我发现最简单的where子句结构本质上是 expression1 [AND expression2 [AND expressionN]] 这很容易在代码中用表达式对象列表表示-然后程序只需遍历每个对象,调用其重写的ToString()方法,并每次追加和(最后一个除外)。简单。当考虑到或时,就会出现复杂情况:where子句的结构变得复杂 expression1 [[AND|OR] expr

我正在VB.NET中创建一个生成SQL字符串的库。然而,生成
WHERE
子句(以及类似的结构)给了我一个问题。我发现最简单的where子句结构本质上是

expression1 [AND expression2 [AND expressionN]]
这很容易在代码中用
表达式
对象列表表示-然后程序只需遍历每个对象,调用其重写的
ToString()
方法,并每次追加
(最后一个除外)。简单。当考虑到
时,就会出现复杂情况:where子句的结构变得复杂

expression1 [[AND|OR] expression2 [[AND|OR] expressionN]]
我现在需要既能保存所有表达式,又能跟踪每个表达式是否被
分隔开来,这是
的基本集合(expr1,andro1,expr2,andro2,…exprN,andron)

我还考虑过结构也可以嵌套,例如:

(expression1 [[AND|OR] expression2]) [AND|OR] (expression3 [[AND|OR] expression4])
其中,每个圆括号中的一半本身就是一个表达式。因此,我认为解决方案是进一步扩展
Expression
类,这样一个表达式可以是一个表达式链:我有一个新类
Expression fromChainofExpressions

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
主要方法:

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)

下面是如何面对您的问题的建议:

Public Class ExpressionFromChainOfExpressions
    Inherits Expression

    Private ExprChain As List(Of Expression)
    Private ExprConn As List(Of Connector)
    Public Enum Connector
        AndConn
        OrConn
    End Enum
    Public Sub AddExpression(Expr As Expression) 'Might have to be changed to account for connectors
        If ExprChain Is Nothing Then ExprChain = New List(Of Expression)
        ExprChain.Add(Expr)
    End Sub
    Public Overrides Function ToString() As String
        Dim outStr As String = "("
        For i = 0 To ExprChain.Count - 1
            outStr &= ExprChain(i).ToString()
            If i < ExprChain.Count - 1 Then
                outStr &= 'will account for the given connector (as stored in ExprConn)
            End If
        Next
        Return outStr & ")"
    End Function
End Class
公共类表达式fromChainofExpressions
继承表达式
私有扩展为列表(表达式)
专用ExprConn As列表(连接器)
公共枚举连接器
安德康
奥康
结束枚举
可能必须更改Public Sub AddExpression(Expr As Expression)“”以考虑连接器
如果ExprChain为Nothing,则ExprChain=新列表(表达式)
ExprChain.Add(Expr)
端接头
Public将函数ToString()重写为字符串
Dim OUNTR As String=“(”
对于i=0的表达式,计数为-1
outtr&=ExprChain(i).ToString()
如果我

我不是100%确定你到底想要完成什么;但您知道和/或(以及像AndAlso这样的替代方案)是ExpressionType枚举()的一部分,不是吗?是的,谢谢,我知道。为了澄清,这里的
/
只是一个输出字符串,需要存储在某个地方并用于链接表达式(程序本身并不使用它们来运行条件检查)。对于所有的程序来说,它可能是
香蕉
/
华夫饼
——关键是我需要某种方法来定义一个链,其中链中的每个链接都由
分开(或
香蕉
华夫饼
):)你能用类的输入写一个实际的例子吗(ExpressionFromChainOfExpressions变量为…)和ToString重写函数的预期输出(当执行.ToString()时,我想得到…)?这肯定有助于明确您想要的确切内容。添加了示例代码(这里没有包括表达式的其他几个具体实现,表达式还有一些其他的活动部分,但它们并不相关,因此为了简洁起见省略)谢谢。我认为你的代码有一些错误,但至少现在给出了一个足够清晰的画面。请简要回复。我回到这里是为了发布我自己在咖啡休息脑波中找到的答案(我发现咖啡休息有时是我一天中最有效率的部分!)…它几乎与此解决方案一字不差。我的使用字符串而不是枚举,因此我确实可以使用
a=b华夫饼干c>100
,尽管我仍在讨论使用哪个。我的还有一个
IsNested
布尔成员,它决定是否包装
()
围绕输出,这允许更好地控制更复杂的嵌套。在任何情况下,完美的答案,谢谢!@kai欢迎您。我建议您使用枚举。它比看起来有用得多;主要是当您必须大量使用给定类时。
Public Class ExpressionFromChainOfExpressions
    Inherits Expression

    Private ExprChain As List(Of Expression)

    'Alternatively use an Enum as per varocarbas's solution 
    'for better consistency control
    Private ChainWord As String

    'If true, wraps ( ) around ToString()'s output
    Private IsNested As Boolean

    Public Sub New(ByVal ChainWord As String, ByVal IsNested As Boolean)
        Me.ChainWord = ChainWord
        Me.IsNested = IsNested
    End Sub

    Public Sub AddExpression(ByVal Expr As Expression)
        If ExprChain Is Nothing Then ExprChain = New List(Of Expression)
        ExprChain.Add(Expr)
    End Sub

    Public Overrides Function ToString() As String
        Dim outStr As String = ""
        If IsNested Then outStr = "("

        For i = 0 To ExprChain.Count - 1
            outStr &= ExprChain(i).ToString()
            If i < ExprChain.Count - 1 Then
                outStr &= String.Format(" {0} ", ChainWord)
            End If
        Next

        If IsNested Then outStr = ")"

        Return outStr
    End Function
End Class
expr1 AND expr2 OR (exp3 AND (expr4 OR expr5 AND expr6 AND expr7))