"There is already an open DataReader..." 重用还是处置数据库连接?

"There is already an open DataReader..." Reuse or Dispose DB Connections?

请帮助...。当我 select 来自 Mysql table 的数据显示 "There is already an open DataReader associated with this Connection which must be closed first. vb.net"

Private Sub cmbJobCategoryVisa_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmbJobCategoryVisa.SelectedIndexChanged
    ''"
    Dim MyCommand As New MySqlCommand("SELECT jobcategorycode FROM jobcategory WHERE jobcategory='" & Me.cmbJobCategoryVisa.SelectedItem & "'", MyConnection)
    Dim MyReader As MySqlDataReader = MyCommand.ExecuteReader
    While MyReader.Read
        If MyReader.HasRows = True Then
            Me.txtJobCategoryCodeVisa.Text = MyReader("jobcategorycode")
        End If
    End While
    MyReader.Close()
    MyCommand.Dispose()
End Sub

'''在执行下面的代码时,显示图像错误

    Private Sub txtEmpNo_Validating(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles txtEmpNo.Validating
    Dim MyCommand5 As New MySqlCommand("SELECT * FROM employeesmaster WHERE empno='" & Me.txtEmpNo.Text & "'", MyConnection)
    Dim MyDataReader5 As MySqlDataReader = MyCommand5.ExecuteReader
    If MyDataReader5.HasRows = True Then
        While MyDataReader5.Read
            Me.txtEmpName.Text = MyDataReader5("name")
            Me.cmbNationality.Text = MyDataReader5("nationality")
            Me.cmbJobCategoryVisa.Text = MyDataReader5("jobcategoryvisa")
            If Not IsDBNull(MyDataReader5("image")) Then
                Dim ImageData As Byte() = DirectCast(MyDataReader5("image"), Byte())
                Dim MemoryStream As New IO.MemoryStream(ImageData)
                Me.pbxEmpImage.Image = Image.FromStream(MemoryStream)
            Else
                Me.pbxEmpImage.Image = Nothing
            End If
        End While
    Else
    End If
    MyDataReader5.Close()
    MyCommand5.Dispose()
End Sub

很明显,您正在使用一个单一的全局连接,并且显然将其保持打开状态。如前所述,您不应重用或存储您的连接。创建连接的成本很低,并且 .NET 针对根据需要创建连接进行了优化。

您的代码中有很多东西没有被关闭和处置。应该是。处置不仅可以防止您的应用程序泄漏资源,而且 使用为每个任务新创建的 DB 对象也不会发生这种错误。

连接数
由于创建它们涉及 回转,因此您可以编写一个函数来创建(并可能打开)一个新的连接,而不必在任何地方粘贴连接字符串。这是使用 OleDB 的一般示例:

Public Function GetConnection(Optional usr As String = "admin",
                       Optional pw As String = "") As OleDbConnection
    Dim conStr As String
    conStr = String.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};User Id={1};Password={2};",
                      dbFile, usr, pw)

    Return New OleDbConnection(constr)
End Function

Using
在 Using 块中使用它,以便处理它:

Using con As OleDb.OleDbConnection = GetConnection()
    Using cmd As New OleDbCommand(sql.Value, con)

        con.Open()
        Using rdr As OleDbDataReader = cmd.ExecuteReader()
           ' do stuff

        End Using      ' close and dispose of reader
    End Using          ' close and dispose of command
End Using              ' close, dispose of the Connection objects

每个 Using 语句创建一个新的目标对象,并将其放置在块的末尾。

一般来说,任何具有 Dispose 方法的东西都可以而且应该在 Using 块中使用,以确保它被处理掉。这将 包含 您的代码中使用的 MemoryStreamImage

Using 块可以是 "stacked" 以指定多个对象并减少缩进(注意第一行末尾后的逗号):

Using con As OleDb.OleDbConnection = GetConnection(),
    cmd As New OleDbCommand(sql.Value, con)
    con.Open()
    ...
End Using       ' close and dispose of Connection and Command

有关详细信息,请参阅:


can u pls convert this code to Mysql connection... my connection string is...

基本MySQL连接:

' module level declaration 
Private MySQLDBase as String = "officeone"

Function GetConnection(Optional usr As String = "root",
                       Optional pw As String = "123456") As MySqlConnection
    Dim conStr As String
    conStr = String.Format("Server=localhost;Port=3306;Database={0};Uid={1}; Pwd={2};", 
         MySQLDBase, usr, pw)

    Return New MySqlConnection(constr)
End Function

个人对于MySql,我在方法中使用了一个class和一个ConnectionStringBuilder。我使用了很多很酷的选项,但这些选项因项目而异,例如数据库和默认应用程序登录。以上使用所有默认值。