2011-04-02 75 views
2

我使用的是帶有mysqlConnector的Visual Studio 2010(C#),一切看起來都很好。 但是,當我嘗試從服務器請求某些東西時,出現此錯誤:已經有一個開放的DataReader與此連接相關聯,必須先關閉

「已經有一個與此連接關聯的打開的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 
} 

我哪裏錯了?

+0

[例外:已經有與此連接相關聯的打開的DataReader必須首先關閉]的可能重複(http://stackoverflow.com/questions/5440168/exception-there-is -already-AN-開放的DataReader相關與 - 此連接-w)的 – BartoszKP 2014-08-02 11:12:29

回答

1

你沒有處理你的對象,這基本上意味着你之前對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 ...; 
     } 
     ... 
    } 
    ... 
} 
1

一些建議,可以幫助:

首先,在你上面的代碼在調用CreateCommand兩次,也不需要。

塞康,您可以實例化你的命令有點不同,使這個更容易閱讀:

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

然後調用ExecuteReader。

第三,上面的代碼不顯示連接何時打開。你確定它是開放的嗎?你確定你還沒有用打開的連接調用數據閱讀器,但沒有關閉它?

第四,您應該儘可能晚地打開連接並儘早關閉連接。你看起來像你的代碼將打開連接並保持打開狀態,但我不確定你的意圖。

我會建議使用使用語法:

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 

修改上面的代碼,您的具體情況....

1

不要試圖單獨與獲取數據的連接。打開電話實際上可能根本不會進入數據庫,您在此時不會檢測到問題。請注意使用語句來關閉連接。添加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); 
    } 
} 
相關問題