已经有一个与此Connection关联的开放DataReader,必须先关闭它

时间:2011-04-02 15:00:59

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

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

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

这是我的代码:

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
}

我哪里错了?

3 个答案:

答案 0 :(得分:1)

你没有丢弃你的对象,这基本上意味着你先前调用getAllConseillers或类似的方法打开了一个仍然打开的数据阅读器。

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

  1. 的MySqlConnection
  2. 的MySqlCommand
  3. 了MySqlDataReader
  4. 基本上,我会将代码更改为:

    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 ...;
            }
            ...
        }
        ...
    }
    

答案 1 :(得分:1)

一些可能有用的建议:

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

Secon,您可以将您的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

根据您的情况修改上述代码....

答案 2 :(得分:1)

不要尝试将连接与get数据分开。对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);
    }
 }