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

1 回しか実行されないように見えますが (?)、これはなぜですか?また、モジュールでクエリを宣言する適切な方法は何ですか?

私は実際に大量のクエリを持っています。より整理されたコーディングのためにそれらを 1 か所に保存したいと考えています。

4

3 に答える 3

0

私が ASP.NET と Access で採用したアプローチの 1 つは、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

変更したFillCategoryコードでは、次のように呼び出しましたが、結果を保存しませんでした:

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

それはオブジェクトを作成しましたOleDbCommandが、すぐに破棄されます。次に、次のように呼び出します。

Dim dr = getCategoryParent.ExecuteReader

2 番目の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

EDIT 2: getCategoryParent現在、モジュールのプロパティとして定義されています。つまり、getCategoryParentメソッドは、ループごとに 1 回ではなく、モジュールが最初にインスタンス化されたときに 1 回実行されます。そのメソッドを関数に変更すると、コードはループごとに 1 回実行され、期待どおりに 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

モジュールに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 に答える