我有一个关于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
看起来只执行一次(?)为什么这是在模块中声明查询的正确方法是什么?
我实际上有很多查询,我想将它们存储在一个地方,以便进行更有条理的编码。
答案 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