"已经有一个开放的DataReader ......"重用或配置数据库连接?

时间:2015-01-29 11:41:38

标签: .net vb.net connection-pooling

请帮助....当我从Mysql表中选择数据时,它显示“已经有一个与此Connection关联的开放DataReader必须先关闭.vb.net”Error showing..

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

1 个答案:

答案 0 :(得分:6)

很明显,您正在使用单个全局连接,并且显然已将其保持打开状态。如前所述,您不应重复使用或存储您的连接。连接创建起来很便宜,并且.NET已经过优化,可以根据需要创建它们。

您的代码中有许多内容未被关闭和处理。应该是。处置不仅可以防止您的应用程序泄漏资源,而且使用新创建的数据库对象为每项任务发生此类错误。

<强>连接
由于 旋转涉及创建它们,您可以编写一个函数来创建(并且可能打开)一个新的Connection,并避免必须在任何地方粘贴连接字符串。以下是使用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 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块可以&#34;堆叠&#34;指定多个对象并减少缩进(请注意第一行结束后的逗号):

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,我个人,我在方法中使用了一个类和一个ConnectionStringBuilder。我使用了许多很酷的选项但是项目与项目之间的区别在于数据库和默认应用程序登录。以上使用了所有默认值。