将所有查询存储在模块中?

时间:2013-06-06 08:48:39

标签: sql database vb.net visual-studio-2012

我有一个关于VBNET的快速问题,我目前正在使用VS 2012 Express和Microsoft Access作为我的数据库。

我的问题是,如何将查询放在模块中而不是将查询放在表单本身? 让我们说我在frmStock中有这个功能:

frmStock:

Public Sub FillCategory(ByVal Key As String, ByVal Txt As String, ByVal N As TreeNode)
    Dim TD As TreeNode

    If N Is Nothing Then
        TD = tvCategory.Nodes.Add(Key, Txt)
    Else
        TD = N.Nodes.Add(Key, Txt)
    End If

    Dim cmd As New OleDbCommand("SELECT * FROM Category WHERE Category_Parent = ?", conn)
    cmd.Parameters.AddWithValue("Category_Parent", Key)

    Dim dr = cmd.ExecuteReader
    Do While dr.Read()
        FillCategory(dr("Category_ID"), dr("Category_Name"), TD)
    Loop
    dr.Close()
    cmd.Dispose()
End Sub

我想搬家

Dim cmd As New OleDbCommand("SELECT * FROM Category WHERE Category_Parent = ?", conn)

代替模块。

我尝试过:

Module queryCollection

    Public getCategoryParent As New OleDbCommand( _
            "SELECT * FROM Category WHERE Category_Parent = ?", conn)

End Module

并将我的FillCategory函数修改为:

Public Sub FillCategory(ByVal Key As String, ByVal Txt As String, ByVal N As TreeNode)
    Dim TD As TreeNode

    If N Is Nothing Then
        TD = tvCategory.Nodes.Add(Key, Txt)
    Else
        TD = N.Nodes.Add(Key, Txt)
    End If

    getCategoryParent.Parameters.AddWithValue("Category_Parent", Key)

    Dim dr = getCategoryParent.ExecuteReader

    Do While dr.Read()
        FillCategory(dr("Category_ID"), dr("Category_Name"), TD)
    Loop
    dr.Close()
    getCategoryParent.Dispose()
End Sub

更新:
一些屏幕截图我的问题:

我的数据库: http://puu.sh/39CMV.PNG

在将我的查询移出模块之前: http://puu.sh/39D0M.PNG

将我的查询移出模块后: puu.sh/39CVV.PNG

看起来只执行一次(?)为什么这是在模块中声明查询的正确方法是什么?

我实际上有很多查询,我想将它们存储在一个地方,以便进行更有条理的编码。

3 个答案:

答案 0 :(得分:0)

在修改后的FillCategory代码中,您调用了以下内容但从未保存过结果:

getCategoryParent.Parameters.AddWithValue("Category_Parent", Key)

创建了一个OleDbCommand对象,然后立即将其丢弃。然后你打电话:

Dim dr = getCategoryParent.ExecuteReader

创建第二个OleDbCommand对象但没有参数值。

修改您的代码,如:

Dim cmd = getCategoryParent.Parameters.AddWithValue("Category_Parent", Key)
Dim dr = cmd.ExecuteReader

编辑:以下将解决这两个问题。

Dim cmd = getCategoryParent
cmd.Parameters.AddWithValue("Category_Parent", Key)
Dim dr = cmd.ExecuteReader

以前,cmd变量由VB Infer编写为OleDbParameter对象,该对象没有ExecuteReader方法。这是通过这种方式推断的,因为它是通过内联完成的.Parameters.AddWithValue("Category_Parent", Key)代码调用的方式。

通过此更改,cmd已正确设置为OleDbCommand变量,现在您可以根据需要多次使用AddParameter方法。

编辑2: getCategoryParent目前被定义为模块的属性。这意味着getCategoryParent方法在首次实例化模块时执行一次,而不是每个循环执行一次。将该方法更改为Function,现在每个循环执行一次代码,并按预期加载TreeView。

Public Function getCategoryParent() As OleDbCommand
    Return New OleDbCommand("SELECT * FROM Category WHERE Category_Parent = ?", conn)
End Function

答案 1 :(得分:0)

我在ASP.NET和Access中采用的一种方法是将SQL作为文件保存到文件夹中,然后使用像这样的单例加载它:

Public Class FileHandler

    Public Shared Function LoadToString(ByVal pName As String) As String
        Dim rV As String
        Dim fio As StreamReader = File.OpenText(pName)
        rV = fio.ReadToEnd()
        fio.Close()
        Return rV
    End Function

End Class

然后从你的代码中调用它......

...
dim sqlStr As String = FileHandler.LoadToString("sql/mySqlStatement.sql")
...
但是,它很可能不是最好的解决方案。这样做的主要优点是您可以动态修改SQL,而无需重新编译应用程序。

另一种方法是将您的SQL语句存储为web.config中的名称值对,但同样,这不是一个非常好的解决方案。

除非有人对此提出更好的建议,否则我认为这将是最糟糕的选择!

答案 2 :(得分:0)

如何将SQL字符串放在模块上..

Module queryCollection

    Public sCatParent As String = "SELECT * FROM Category WHERE Category_Parent = ?"

End Module 

你称它为......

getCategoryParent As New OleDbCommand(sCatParent,conn)

getCategoryParent.Parameters.AddWithValue("Category_Parent", Key)

Dim dr = getCategoryParent.ExecuteReader