【问题标题】:Close Connection / MySqlDataReader doesn't work关闭连接/MySqlDataReader 不起作用
【发布时间】:2017-09-08 17:03:12
【问题描述】:

我有一堂课,我的 MysqlConnection 在那里:

public class DB
{
    private static MySqlConnection _Connection;
    public static MySqlConnection Connection
    {
        get
        {
            if(_Connection == null)
            {
                string cs = string.Format("SERVER={0}; DATABASE={1}; UID={2}; PWD={3};", SERVER_ADRESS, DATABASE, UID, PWD);
                _Connection = new MySqlConnection(cs);
            }

            if(_Connection.State == System.Data.ConnectionState.Closed)
                try
                {
                    MessageBox.Show("MySQL Connection ist geschlossen. Öffne Sie");
                    _Connection.Open();
                }
                catch(MySqlException ex)
                {
                    switch (ex.Number)
                    {
                        case 0:
                            MessageBox.Show("Verbindung zum Server konnte nicht hergestellt werden.");
                            break;
                        case 1045:
                            MessageBox.Show("Ungültiger Benutzername/Passwort.");
                            break;
                        default:
                            MessageBox.Show(ex.Message);
                            break;
                    }
                }
            return _Connection;
        }
    }
}

所以我可以在所有其他类中使用此连接DB.Connection

但现在我得到“DataReader 已打开”。 但是我所有的 DataReader 都在使用中。

我们从我的登录页面开始:

using (loginreader = cmd.ExecuteReader())
            {
                if (loginreader.Read())
                {
                    DB.Connection.Close();
                    return true;
                }
                else
                {
                    DB.Connection.Close();
                    return false;
                }
               loginreader.Close();
            } 

我猜这行不通。但是登录后的第一个错误消息我在第 83 行上另一个类:

DataTable schema = null;

            using (var schemaCommand = new MySqlCommand("SELECT * FROM " + firmCustomerTablename, connection))
            {
                using (var reader = schemaCommand.ExecuteReader(CommandBehavior.SchemaOnly))
                {
                    schema = reader.GetSchemaTable();
                }
            }

这也在使用中。所以我不明白为什么我会收到这个错误。我猜想关闭连接/DataReaders 不起作用。

在此更改之前,我为每个站点建立了连接。但是我的程序没有很好的表现。所以我决定建立一个始终打开的连接,然后只调用这个打开的连接的查询。现在我得到了 DataReader 错误。

有人可以解释一下,为什么使用没有关闭 DataReader?第 83 行不是 DataReader,它是 var,所以我不知道为什么会在这一行出现此错误。

【问题讨论】:

  • 为整个实例设置一个静态连接并不是一个好的解决方案。您应该为所做的每个查询或更新打开连接。这样做会导致超出您所描述的更多问题。如果这导致性能不佳,请解决该问题(确保连接正确池化,及时处置/关闭它们等)
  • 每 5 秒打开一次连接会破坏性能。因为所有东西都会从数据库中读取。单击按钮会打开一个包含数据库内容的窗口。再次单击另一个按钮等。
  • 每 5 秒创建一次连接不会影响性能。如果是,则某些设置不正确。您是否真的证实它正在发生或只是假设?请参阅:*.com/questions/9705637/…*.com/questions/26089420/…

标签: c# mysql wpf


【解决方案1】:

听起来您的问题与连接状态管理有关?我可能不完全理解您的要求,但根据设计,连接上下文中的 using 语句将关闭连接。它们是try {} catch {} finally 的语法糖。我经常看到没有使用IDisposable 并且没有正确处理/关闭的连接对象、命令对象等示例。

在这段代码中,我没有看到再次打开连接以执行命令。

 DataTable schema = null;

        using (var schemaCommand = new MySqlCommand("SELECT * FROM " + firmCustomerTablename, connection))
        {
            using (var reader = schemaCommand.ExecuteReader(CommandBehavior.SchemaOnly))
            {
                schema = reader.GetSchemaTable();
            }
        }

这是一个基本的想法:

        using (var conn = new SqlConnection(connectionString: ""))
        {
            conn.Open();

            using (var cmd = new SqlCommand(cmdText: "cmdText", connection: conn))
            {
                using (var reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        //
                    }
                }
            }

        }

文档:MSDN SqlConnection Class

【讨论】:

  • 我建议展示如何安全地关闭连接,因为那是他最初的问题。您可以从添加cmd.ExecuteReader(CommandBehavior.CloseConnection) 开始。这将自动关闭读取循环完成的阅读器。因此,您无需检查读者状态。您可以简单地使用 null 属性,然后关闭连接。
  • 我知道您的 using 语句否定了这一点,但我说可能值得先了解一下发生了什么?在深入了解语法糖之前。