2012-03-16 36 views
4

我創建了以下方法:如何在呼叫者與他們結束後關閉連接?

public System.Data.OleDb.OleDbDataReader GetReader(string sqlQuery) 
    { 

      System.Data.OleDb.OleDbConnection myConnection = new System.Data.OleDb.OleDbConnection(); 
      LoadConnectionStrings(); 
      myConnection.ConnectionString = ConnectionString; 
      myConnection.Open(); 
      System.Data.OleDb.OleDbCommand myCommand = new System.Data.OleDb.OleDbCommand(sqlQuery, myConnection); 
      System.Data.OleDb.OleDbDataReader myReader = null; 
      myReader = myCommand.ExecuteReader(); 

      return myReader; 

    } 

代碼千行依賴於它,我想我是不是真的想,當我實現了它......

無論如何,

。如果我以這種方式檢索閱讀器,我無法關閉連接,並且如果在閱讀器調用read()方法之前關閉連接,它將在閱讀並說與數據庫的連接需要時爆炸被打開。

問題是,我如何關閉以前代碼體的連接?或者所有的連接一般也許..

從我讀的here如果你沒有專門調用'close()'它不會被關閉,如果你使用的是2003訪問文件,在一個受到傷害的世界裏,你離開你的世界

+0

爲什麼不在關閉之前關閉? – 2012-03-16 16:49:42

+1

@Dor因爲它沒有消耗任何數據在這一點上 – 2012-03-16 16:50:20

+0

不幸的是,你不能:/ – 2012-03-16 16:51:37

回答

12

在這種情況下,連接需要保持開放狀態才能讓讀者工作 - 但是,ExecuteReader有一個重載,可以讓你爲讀者指定一個標誌來關閉連接讀者被關閉:

myReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection); 

這允許呼叫者使用:

using(var reader = GetReader(query)) { 
    //... 
} 

並且當調用者完成讀寫器時連接將被完全關閉。

+0

誰會想到2個單詞會節省數千行代碼^ _^ – 2012-03-16 16:58:20

+1

不過,如果你有一個方法返回一個' IDataReader'它需要包含一個try/catch,在'command.ExecuteReader'引發的情況下關閉連接。 – Joe 2012-03-16 18:33:53

1

不知道它是否完全解決了您的問題,但您可以使用IDBcommand.ExecuteReader(CommandBehavior)過載。

如果您通過CommandBehavior.CloseConnection,那麼當您的閱讀器關閉時,數據庫連接將會關閉。

1

我同意Marc的看法,但是希望用您的方法指出缺陷。

該機制隱藏了來自調用者的連接,因此調用者不能將其用於針對數據庫的其他操作。它還將範圍與讀者的生命週期聯繫在一起,因此如果要採取其他行動,那麼在處置讀者之前必須進行。

讓調用者控制連接可能會更好,只需將連接傳遞給GetReader方法即可。

1

我用做這樣的事情:

IDataReader GetReader(...) 
{ 
    IDbConnection connection = ...; 
    try 
    { 
     IDbCommand command = ...; 
     command.Connection = connection; 
     connection.Open(); 
     return command.ExecuteReader(CommandBehavior.CloseConnection); 
    } 
    catch 
    { 
     connection.Close(); 
     throw; 
    } 
} 

這不會關閉IDbCommand,但在我的經驗,這是OK,只要連接被關閉。