【问题标题】:"There is already an open DataReader..." Reuse or Dispose DB Connections?“已经有一个打开的 DataReader...” 重用或处理数据库连接?
【发布时间】:2015-03-28 15:05:50
【问题描述】:

请帮助....当我从 Mysql 表中选择数据时,它显示“已经有一个打开的 DataReader 与此连接关联,必须先关闭。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

【问题讨论】:

  • 不要重复使用连接。使用Using-statement 确保它们被丢弃->即使出现错误也尽快关闭。数据读取器也使用Using-statement。
  • 能否请您发布此图片的代码?
  • 正如错误消息所说,一个连接上不能有两个打开的 DataReader。
  • 您是否在数据读取器循环中使用数据读取器?所以不要

标签: .net vb.net connection-pooling


【解决方案1】:

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

您的代码中有很多东西没有被关闭和处置。应该是。 Disposing 不仅可以防止您的应用程序泄漏资源,而且为每个任务使用新创建的 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 块可以“堆叠”以指定多个对象并减少缩进(注意第一行末尾的逗号):

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。我使用了许多很酷的选项,但它们因项目而异,例如数据库和默认应用程序登录。以上使用所有默认值。

【讨论】:

  • Plutonix,,, 这个编码非常好....你能把这个代码转换成Mysql连接吗...我的连接字符串在下面..Dim MyConnection As New MySqlConnection("Server=localhost;User=root;Database=officeone;port=3306;Password=123456;")
  • 使用您的代码成功完成了这项工作,出色的编码.. 非常感谢.. 我在这里添加代码作为答案..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-06
相关资源
最近更新 更多