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

Posted

技术标签:

【中文标题】MySqlConnection 上的“InvalidOperationException:连接必须有效且打开”【英文标题】:"InvalidOperationException : Connection must be valid and open" On MySqlConnection 【发布时间】:2019-05-15 19:36:17 【问题描述】:

我正在从事 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】:

在 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

【讨论】:

感谢您的所有提示和代码!你在这里真的帮了我!现在我只需要理解所有的代码,但你真的帮助我做了我想做的事。 @Yoleo 第一句话(...) 尝试在整个应用程序中重用同一个连接对象通常不是一个好主意(...) ,这不仅仅是最佳实践。这是许多问题的隐藏根源,尤其是在许多情况下表现非常糟糕。

以上是关于MySqlConnection 上的“InvalidOperationException:连接必须有效且打开”的主要内容,如果未能解决你的问题,请参考以下文章

&diesel::MysqlConnection 没有实现特征diesel::Connection

未定义的属性:Illuminate\Database\MySqlConnection - 查询包含参数,但是我收到此错误。怎么了

此 MySqlConnection 已用于带有 MySQL 的 .net

MySqlConnection.Open 无限期挂起

无法使用 MySQLConnection 连接到远程数据库

This MySqlConnection is already in use