【问题标题】:There is already an open DataReader associated with this Connection which must be closed first已经有一个打开的 DataReader 与此 Connection 关联,必须先关闭
【发布时间】:2011-04-02 15:00:59
【问题描述】:

我正在使用带有 mysqlConnector 的 Visual Studio 2010 (C#),一切似乎都很好。 但是,当我尝试从服务器请求某些内容时,我收到此错误:

“已经有一个打开的 DataReader 与此 Connection 关联,必须先关闭它。”

这是我的代码:

gc.connect();

List<Conseiller> conseillers = gc.getAllConseillers();

--

public void connect() 
{
    string connStr = "SERVER=localhost;UID=root;DATABASE=Projet;Password=root";
    oConn = new MySqlConnection(connStr);

    try 
    {
        oConn.Open();
        Console.WriteLine("Successfully connected to the data base");
    } 
    catch (OdbcException caugth) 
    {
        /* Traitement de l'erreur */
        Console.WriteLine(caugth.Message);
    }
}

-- 

public List<Conseiller> getAllConseillers()
{
    MySqlCommand oComm = oConn.CreateCommand();

    oComm = oConn.CreateCommand();

    Console.WriteLine("SELECT * FROM conseillers");
    oComm.CommandText = "SELECT * FROM conseillers";

    MySqlDataReader oReader = oComm.ExecuteReader(); // Error here
}

我哪里错了?

【问题讨论】:

标签: c# .net mysql database visual-studio


【解决方案1】:

不要尝试将连接与获取数据分开。对 Open 的调用实际上可能根本不会进入数据库,此时您将不会检测到问题。注意用于关闭连接的 using 语句。根据需要添加 SEH

List<Conseiller> conseillers = gc.getAllConseillers();

public void getAll() {
  string connStr = "SERVER=localhost;UID=root;DATABASE=Projet;Password=root";
  using (oConn = new MySqlConnection(connStr))
  using (MySqlCommand oComm = oConn.CreateCommand())
  {
    oConn.Open();
    oComm.CommandText = "SELECT * FROM conseillers";

    MySqlDataReader oReader = oComm.ExecuteReader(); // no Error here
    // user reader here
    } catch (OdbcException caugth) {
        /* Traitement de l'erreur */
        Console.WriteLine(caugth.Message);
    }
 }

【讨论】:

    【解决方案2】:

    您没有处理您的对象,这基本上意味着您之前对 getAllConseillers 或类似方法的调用打开了一个仍处于打开状态的数据读取器。

    您问题中的以下对象是一次性的(即实现IDisposable),您应该将它们全部丢弃:

    1. MySqlConnection
    2. MySqlCommand
    3. MySqlDataReader

    基本上,我会将代码更改为如下所示:

    using (var gc = new Whatever())
    {
        gc.connect();
        List<Conseiller> conseillers = gc.getAllConseillers();
    }
    
    --
    
    public void connect()
    {
        string connStr = "SERVER=localhost;UID=root;DATABASE=Projet;Password=root";
        oConn = new MySqlConnection(connStr);
        try
        {
            oConn.Open();
            Console.WriteLine("Successfully connected to the data base");
        }
        catch (OdbcException ex)
        {
            /* Traitement de l'erreur */
            Console.WriteLine(ex.Message);
            oConn.Dispose();
            oConn = null;
            // optional: throw;
        }
    }
    
    -- 
    
    public List<Conseiller> getAllConseillers()
    {
        using (MySqlCommand oComm = oConn.CreateCommand())
        {
            Console.WriteLine("SELECT * FROM conseillers");
            oComm.CommandText = "SELECT * FROM conseillers";
            using (MySqlDataReader oReader = oComm.ExecuteReader()) // No error here
            {
                // process the result in oReader here
                return ...;
            }
            ...
        }
        ...
    }
    

    【讨论】:

      【解决方案3】:

      一些可能有帮助的建议:

      首先,在您上面的代码中,您已经调用了两次 CreateCommand 并且不需要。

      其次,您可以将您的 Command 实例化一点,以使其更易于阅读:

      MySqlCommand oComm = new MySqlCommand("Select * from conseillers", oConn);
      

      然后调用 ExecuteReader。

      第三,您上面的代码在连接打开时不会显示。你确定它是开放的?您确定您还没有通过打开的连接调用数据读取器并且没有关闭它吗?

      第四,您应该始终尽可能晚地打开连接并尽可能早地关闭它。您拥有的代码似乎要打开连接并使其保持打开状态,但我不确定您的意图。

      我建议使用 Using 语法:

      Using connection As New SqlConnection(connectionString)
              Dim command As New SqlCommand(queryString, connection)
              connection.Open()
              Dim reader As SqlDataReader = command.ExecuteReader()
              Try
                  While reader.Read()
                      Console.WriteLine(String.Format("{0}, {1}", _
                          reader(0), reader(1)))
                  End While
              Finally
                  ' Always call Close when done reading.
                  reader.Close()
              End Try
          End Using
      

      根据你的情况修改上面的代码....

      【讨论】:

        猜你喜欢
        • 2019-01-17
        • 2020-09-25
        • 2011-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-23
        • 2013-07-18
        相关资源
        最近更新 更多