1

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

班级

   //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);
        }

    }
4

3 回答 3

3

我会使用usingwhich 关心处理变量和关闭连接。

班级:

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);
    }
}
于 2016-11-29T07:00:44.423 回答
1

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

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

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

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

在这种情况下,该方法是在另一个类中定义的,因此无法在那里使用 UI 项,因此更好的选择是将 UI 元素、ListBox 传递给该方法并使用阅读器填充它。为此,代码将如下所示:

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 绑定所需的列表
于 2016-11-29T07:17:19.900 回答
0

始终使用 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();
                }
            }       

        }
于 2016-11-29T07:36:48.320 回答