如何以正确的方式管理 mysql 连接而不出错

How to manage the mysql connection in correct way without getting a error

我是 C# 新手,我的方法在 try catch connection is already open 代码中显示如下错误,当我从 Class 方法关闭它时,Form 收到错误 invalid connection。在这里,如果将所有代码放在 FORM 中,它就可以工作。但在这里我得到 MysqlDataReader 作为 return 值。我该如何解决这个错误。

CLASS

   //select all categories
    public MySqlDataReader SelectCategory() {

        try
        {
            MySqlCommand cmd = connection.CreateCommand();
            cmd.CommandText = "SELECT * FROM categories WHERE online = 1";

            connection.Open();
            MySqlDataReader categories = cmd.ExecuteReader();
            return categories;
        }

        catch (Exception ex) {
            MessageBox.Show(ex.Message);
            return null;
        }


    }

表格

    public void show()
    {
        MySqlDataReader rd = db.SelectCategory();

        try
        {
            while (rd.Read())
            {
                listBox1.Items.Add(rd.GetString(1));
            }
        }

        catch (Exception ex) {
            MessageBox.Show(ex.Message);
        }

    }

我会使用 using,它关心处理变量和关闭连接。

CLASS:

public List<string> SelectCategory()
{
    List<string> result = new List<string>();
    string Command = "SELECT * FROM categories WHERE online = 1";
    using (MySqlConnection mConnection = new MySqlConnection(ConnectionString))
    {
        mConnection.Open();
        using (MySqlCommand cmd = new MySqlCommand(Command, mConnection))
        {
            using (MySqlDataReader reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {                        
                    result.Add(reader.GetString(1));
                }
            }
        }
    }
    return result;
}

表格:

public void show()
{
    try
    {
        foreach(string item in SelectCategory())
        {
            listBox1.Items.Add(item);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

DataReader 是用于从数据库检索数据的例外情况,它始终需要打开连接才能从 DataReader 获取值。在您的情况下,您将 MySqlDataReader 传递给调用方法,因此您无法关闭被调用方法的连接,因为 reader 需要打开的连接。所以你的可能性是在关闭 DataReader.

后关闭连接

您可能面临的另一个问题是连接问题(您当前的问题),从您的代码可以看出您没有关闭连接,因此当您第一次调用该方法时,一切都会好起来的。当第二次调用触发时,连接的当前状态将打开,因此当您尝试重新打开连接时它会抛出此类异常。

别担心,您可以使用以下任一方法来解决问题(我不确定这些建议是否对这个社区有效,如果不是请见谅)

  • 将您的 UI 控件传递给 class 方法并将项目添加到列表

在这种情况下,该方法是在另一个 class 中定义的,因此无法在那里使用 UI 项,因此更好的选择是传递 UI 元素, ListBox 添加到该方法并使用 reader 填充它。为此,代码将是这样的:

public MySqlDataReader SelectCategory(ListBox listBox1) 
{

  // fubo's answer here

}
  • 在检查连接状态后生成一个关闭连接的方法,并在 while 完成其迭代时调用该方法。

调用方法如下:

   try
    {
        using (MySqlDataReader reader = db.SelectCategory())
        {
            while (reader.Read())
            {
                listBox1.Items.Add(reader.GetString(1));
            }
        }
        db.CloseConnection(); // will be the method to close the connection
    }
  • 使用 DataTable 代替 DataReader: 将数据获取到 DataTable,然后使用该 DataTable
  • 绑定所需的列表

始终使用 finally 关闭连接,无论发生什么情况,打开后都必须关闭连接。

    public MySqlDataReader SelectCategory() {

            try
            {
                MySqlCommand cmd = connection.CreateCommand();
                cmd.CommandText = "SELECT * FROM categories WHERE online = 1";

                connection.Open();
                MySqlDataReader categories = cmd.ExecuteReader();
                return categories;
            }        
            catch (Exception ex) {
                MessageBox.Show(ex.Message);
                return null;
            }
            finally
            {
                if (connection != null && connection.State == ConnectionState.Open)
                {
                    connection.Close();
                    connection.Dispose();
                }
            }       

        }