"Уже есть открытый DataReader..." Повторное использование или удаление подключений к БД?

Пожалуйста, помогите.... Когда я выбираю данные из таблицы 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

1 ответ

Решение

Очевидно, что вы используете одно глобальное соединение и, очевидно, оставляете его открытым. Как уже упоминалось, вы не должны повторно использовать или хранить ваше соединение. Соединения дешевы в создании, и.NET оптимизирован для их создания по мере необходимости.

В вашем коде есть ряд вещей, которые не закрываются и не удаляются. который должен быть. Утилизация не только предотвращает утечку ресурсов вашим приложением, но такого рода ошибки не могут возникать при использовании вновь созданных объектов БД для каждой задачи.

связи
Поскольку их создание связано с вращением, вы можете написать функцию для создания (и, возможно, открытия) нового соединения и избежать необходимости везде вставлять строку соединения. Вот общий пример использования 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блок для обеспечения его утилизации. Это будет включать в себя MemoryStream а также Image используется в вашем коде.

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 в методе. Я использую много классных опций, но они отличаются от проекта к проекту, например, БД и логин приложения по умолчанию. Выше используются все значения по умолчанию.

Другие вопросы по тегам