避免 NullReferenceException
我对 .NET 编程相当陌生。我试图检查数据库表中是否有设置,如果没有,则创建一些默认设置。问题是,当没有设置时,我需要使用数据读取器进行两次调用,这一直给我带来问题。
我最初只使用一个数据读取器,但尝试使用两个数据读取器来解决我的问题,但没有成功。
然后我尝试关闭数据读取器,但出现错误,因为它返回了空引用。
如果我尝试关闭它,我会遇到一个问题,如果我不关闭它,下一个会给我一个错误,指出此连接上已经有一个打开的数据读取器需要关闭。谁能告诉我如何重构我的代码以使其正常工作(最好使用一个数据读取器)?
我还尝试将 reader.close() 放入另一组 try catch 中,虽然这使我能够捕获错误,但它仍然不会关闭 datareader,所以我不知所措。
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
I'm fairly new to .NET programming. I am trying to check if there are settings in a database table and if not, create some default settings. The problem is that when there are no settings I need to make two calls with the datareader and it keeps giving me problems.
I originally was only using one datareader but made two to attempt resolving my issue, didn't work.
Then I tried closing the datareader and I get errors because it returned a nullreference.
If I try to close it I get an issue, if I don't close it the next one gives me an error saying there is already an open datareader on this connection that needs to be closed. Can anyone tell me how I can refactor my code to get this to work (preferably with one datareader)?
I also tried putting the reader.close() in another set of try catch, while that enables me to catch the error, it still doesn't close the datareader so I am at a loss.
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您正在重复使用您的
cmd
对象。实际上,您将每个读取器设置为与命令对象相同的连接。您应该创建 2 个不同的命令对象,并赋予它们自己的数据库连接。另一种选择是从第一个数据读取器获取所需的信息并将其存储在数据表中(使用 MySqlDataAdapter)。如果该信息不可用,请关闭该连接,并使用新的命令对象创建一个新连接。这可能就是我要走的方向。
编辑
您确实需要使用
New SqlConnection()
并让操作系统处理它。You are re-using your
cmd
object. Effectively, you are setting each reader to the same connection as your command objects. You should create 2 different command objects that are given their own database connections.Another option would be to get info you need from the first data reader and store in a datatable (using a MySqlDataAdapter). If that info is not available, close that connection, create a new one with a new command object. This is probably the direction I would go.
Edit
You really need to use
New SqlConnection()
and let the OS handle that.问题是在你的第二个 try 块中,你正在执行一个仍然有打开的阅读器的命令。我使用使用块来帮助保持直线,例如:
The problem is in your second try block you are executing a command that still has an open reader. i use Using blocks to help keep them straight, for example:
我认为问题在于您有两个潜在的问题原因,并且使用您正在使用的代码一次只能解决一个问题。以下是两种可能性:
使用您当前拥有的代码,我认为您已经解决了问题#2,但重新引入了问题 1。如果尚不存在用户设置,则永远不会创建数据读取器,因为执行命令时失败。因此,当您尝试关闭数据读取器时,您会收到错误。当代码没有关闭数据读取器时,您解决了问题#1,但没有解决问题#2。我认为有一些更好的方法可以解决这个问题:
I think the problem is that you have two potential problem causes and can only solve one at a time with the kind of code you are using. Here are the two possibilities:
With the code you currently have, I think you have solved problem #2, but re-introduced problem number 1. If no user settings exist yet, the datareader never gets created because there's a failure executing the command. So when you try to close the datareader, you get an error. When the code did not close the datareader, you solved problem #1, but not #2. I think there are a couple better ways to solve this: