1

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

我的问题是,如何将查询放入模块中,而不是将查询放入表单本身?假设我在 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

似乎只执行一次(?)为什么会这样以及在模块中声明我的查询的正确方法是什么?

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

4

3 回答 3

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变量被InferVB 编辑为一个OleDbParameter对象,它没有ExecuteReader方法。之所以这样推断,是因为它是.Parameters.AddWithValue("Category_Parent", Key)通过内联代码调用的方式。

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

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

Public Function getCategoryParent() As OleDbCommand
    Return New OleDbCommand("SELECT * FROM Category WHERE Category_Parent = ?", conn)
End Function
于 2013-06-06T12:26:29.657 回答
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 中,但同样,这不是一个很好的解决方案。

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

于 2013-06-06T12:43:19.513 回答
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
于 2013-06-06T15:47:13.677 回答