1

私は .NET プログラミングにかなり慣れていません。データベース テーブルに設定があるかどうかを確認しようとしています。ない場合は、デフォルト設定をいくつか作成します。問題は、設定がない場合、データリーダーで 2 つの呼び出しを行う必要があり、問題が発生し続けることです。

私はもともと1つのデータリーダーしか使用していませんでしたが、問題を解決するために2つ作成しましたが、うまくいきませんでした.
次に、データリーダーを閉じようとしましたが、null 参照が返されたためエラーが発生しました。

閉じようとすると問題が発生します。閉じないと、次のエラーで、この接続には閉じる必要がある開いているデータリーダーが既に存在するというエラーが表示されます。コードをリファクタリングしてこれを機能させる方法を誰か教えてもらえますか (できれば 1 つのデータリーダーで)。

また、reader.close() を try catch の別のセットに入れてみましたが、これによりエラーをキャッチできますが、まだデータリーダーを閉じないため、途方に暮れています。

Private Sub Get_Initial_Settings()
    Dim reader1 As MySqlDataReader = Nothing, reader2 As MySqlDataReader = Nothing
    Dim cmd As New MySqlCommand("SELECT depot, size, roc_family, wil_family, ast_family, met_family, ric_family, view FROM vb_dashboard.user_preferences WHERE " & GetUserName() & "", conn)
    Dim hasSettings As Boolean

    'Get Personal Settings or initiate them if necessary
    Try
        reader1 = cmd.ExecuteReader
        hasSettings = True
        MessageBox.Show("Your user settings show you have a selected depot of " & reader1(0).ToString)
    Catch ex As Exception
        'No settings exist, set some up
        MessageBox.Show("You have no settings for this program yet")
        hasSettings = False
    Finally
        reader1.Close()
    End Try

    'User has no preferences, Create some
    'First, create a list of depots to select from and add it to a combobox
    If (hasSettings = False) Then
        Try

            cmd.CommandText = "SELECT depot FROM vb_dashboard.depots ORDER BY depot"
            reader2 = cmd.ExecuteReader
            While (reader2.Read)
                dlgSelectDepot.cbDepotSelect.Items.Add(reader2.GetString(0))
            End While
            'Now show the dialog box to initiate a depot setting
            Me.Hide()
            dlgSelectDepot.Show()
            Me.Show()
            If (dlgSelectDepot.DialogResult = Windows.Forms.DialogResult.Cancel) Then
                Me.Close()
            End If
            cmd.CommandText = "INSERT INTO vb_database.user_preferences SET user='" & GetUserName.ToUpper & "', depot='Rochester'"
            cmd.ExecuteNonQuery()
        Catch ex As Exception
            MessageBox.Show("An error has occurred: " & ex.Message)
        Finally
            reader2.Close()
        End Try
    End If

End Sub
4

3 に答える 3

0

問題は、2つの潜在的な問題の原因があり、使用しているコードの種類で一度に1つしか解決できないことだと思います。2つの可能性があります:

  1. ユーザー設定はまだ存在しません。
  2. 同じコマンドと接続オブジェクトを複数のクエリに再利用しています。

現在のコードで、問題2は解決したと思いますが、問題1が再導入されました。ユーザー設定がまだ存在しない場合、コマンドの実行に失敗したため、データリーダーは作成されません。したがって、データリーダーを閉じようとすると、エラーが発生します。コードがデータリーダーを閉じなかった場合、問題#1は解決しましたが、#2は解決しませんでした。これを解決するためのより良い方法がいくつかあると思います。

  1. ユーザー設定が存在するかどうかを検出するためのより良い方法を見つけてください。たとえば、SELECT COUNT(*)FROM sys.objects where name ='user_preferences'
  2. 閉じようとする前に、「reader1が何もない場合」をチェックしてください。
于 2010-12-18T15:47:56.003 に答える
0

問題は、まだリーダーが開いているコマンドを実行している 2 番目の try ブロックにあります。ブロックを使用して、それらをまっすぐに保つのに役立ちます。次に例を示します。


Using cn As new DbConnection(connectionString)
 cn.Open()
 Using cmd As DbCommand = cn.CreateCommand()
  'first command
  cmd.CommandText = "SELECT depot FROM vb_dashboard.depots ORDER BY depot" 
  Using dr As DbDataReader = cmd.ExecuteReader()
   While dr.Read()
    dlgSelectDepot.cbDepotSelect.Items.Add(reader2.GetString(0))
   End While
   dr.Close()
  End Using
  '
  'next command
  cmd.CommandText = "INSERT INTO vb_database.user_preferences SET user='" & GetUserName.ToUpper & "', depot='Rochester'"
  cmd.ExecuteNonQuery()
 End Using
 cn.Close()
End Using

于 2010-12-17T20:03:02.057 に答える
0

オブジェクトを再利用していcmdます。実際には、各リーダーをコマンド オブジェクトと同じ接続に設定しています。独自のデータベース接続が与えられる 2 つの異なるコマンド オブジェクトを作成する必要があります。

もう 1 つのオプションは、最初のデータ リーダーから必要な情報を取得し、(MySqlDataAdapter を使用して) データ テーブルに格納することです。その情報が利用できない場合は、その接続を閉じ、新しいコマンド オブジェクトで新しい接続を作成します。これはおそらく私が行く方向です。

編集

New SqlConnection()OSにそれを処理させる必要があります。

于 2010-12-17T19:38:48.897 に答える