MySqlConnection上的“ InvalidOperationException:连接必须有效且打开”

时间:2018-12-14 14:06:24

标签: mysql sql vb.net select mariadb

我正在一个VB.Net项目中工作(第一次,我以前是在VBA中工作),我似乎在与MariaDB / MySQL数据库建立连接时遇到困难。
我想获取一列的所有行,以将其用作表单中名为CBClient的ComboBox的源

到目前为止,这里是我的代码:

头等舱:ClassSQL

Imports MySql.Data.MySqlClient
Imports MySql.Data.Types

Public Class ClassSQL
    Public Shared ConfigSQL As String = 
        "DATABASE=(My actual DB);DATA SOURCE=(IP of the server);USER ID=(UserID);PASSWORD=(Password)"

    Public Shared ConnectDB As New MySqlConnection(ConfigSQL)
End Class

和Form类:

Imports MySql.Data.MySqlClient

Public Class NewDossier
    Private Sub NewDossier_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        GetCBClient()
    End Sub

    Sub GetCBClient()
        ClassSQL.ConnectDB.Open()

        Dim Requete As String = "SELECT NomClient FROM MSClients"
        Dim Query As New MySqlCommand(Requete, ClassSQL.ConnectDB)
        Dim rs As MySqlDataReader = Query.ExecuteReader

        Do While rs.Read
            CBClient.Items.Add(rs.GetString("NomClient"))
        Loop

        ClassSQL.ConnectDB.Close()
    End Sub
End Class

在Form类的ClassSQL.ConnectDB.Open()中,我有一个例外:

  

InvalidOperationException:连接必须有效并打开

我的连接有问题吗?还是我做错了什么?
有没有办法指定端口?

1 个答案:

答案 0 :(得分:2)

在ADO.Net中,尝试在整个应用程序中重用相同的连接对象通常不是一个好主意,因为它具有一种称为“连接池”的功能。连接器已经在为您管理。相反,最好为大多数查询创建一个新的连接实例。只需保持连接字符串方便并重复使用即可。与IDisposable / Using模式结合使用时,效果特别好。

此外,最好将查询与连接字符串放在同一个类或模块中,并与应用程序的其余部分隔离开来,其中每个查询都是一个返回数据的函数,并且(通常)接受一个参数告知它要查找什么数据。

Public Module SQL
    'Making this private helps ensure you remember to put database activities here in this class.
    Private ConnectionString As String = "DATABASE=(My actual DB);DATA SOURCE=(IP of the server);USER ID=(UserID);PASSWORD=(Password)"

    'You could also design this function to return a DataTable object, if Iterator blocks aren't your thing
    Public Iterator Function GetMSClients() As IEnumerable(Of String)
        Dim Requete As String = "SELECT NomClient FROM MSClients"

        Using cn As New MySqlConnection(ConnectionString), _
              cmd As New MySqlCommand(Requete, cn)
            cn.Open()

            Using rdr As MySqlDataReader = cmd.ExecuteReader()
                While rdr.Read()
                     Yield rdr.GetString("NomClient")
                End While
            End Using
        End Using
    End Function

End Module

Public Class NewDossier
    Private Sub NewDossier_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        CBClient.Items.AddRange(SQL.GetMSClients().ToArray())
    End Sub
End Class