2013-04-18 15 views
2

我會重用的OracleConnection對象爲多個查詢 所以我寫了一個簡單的類:重用的OracleConnection對象的

public static class DbConnectionsManager 
    { 
     /// <summary> 
     /// 
     /// </summary> 
     private static OracleConnection _dbConnection = null; 


     /// <summary> 
     /// 
     /// </summary> 
     /// <param name="aConnectionString"></param> 
     /// <returns></returns> 
     public static OracleConnection GetDatabaseConnection(string aConnectionString) 
     { 
      try 
      { 
       if (_dbConnection == null) 
       { 
        _dbConnection = new OracleConnection(aConnectionString); 
        _dbConnection.Open(); 
        return _dbConnection; 
       } 

       if (_dbConnection.State == System.Data.ConnectionState.Closed) 
       { 
        _dbConnection.ConnectionString = aConnectionString; 
        _dbConnection.Open(); 
        return _dbConnection; 
       } 

       if (!_dbConnection.ConnectionString.Equals(aConnectionString)) 
       { 
        _dbConnection.Close(); 
        _dbConnection.ConnectionString = aConnectionString; 
        _dbConnection.Open(); 
        return _dbConnection; 
       } 

       return null; 
      } 
      catch (Exception e) 
      { 

       return null; 
      } 
     } 
    } 

這樣我就可以使用連接多次:

using (OracleConnection connection = 
      DbConnectionsManager.GetDatabaseConnection(aDbConnectionString)) 
      { 
       OracleCommand command = connection.CreateCommand(); 
       string sql = "SELECT * FROM MYTABLE"; 
       command.CommandText = sql; 

       OracleDataReader reader = command.ExecuteReader(); 
       while (reader.Read()) 
       { 
        string myField = (string)reader["EXAMPLE"]; 
        Console.WriteLine(myField); 
       } 
      } 

當我第一次調用該方法時,一切正常。 如果我記得該方法的靜態對象是!= null,但連接結果關閉! 我從不關閉連接!

當您嘗試重新打開我有這樣的例外

.... 
if (_dbConnection.State == System.Data.ConnectionState.Closed) 
       { 
        _dbConnection.ConnectionString = aConnectionString; 
        _dbConnection.Open(); 
        return _dbConnection; 
       } 
... 

錯誤

Message = "Cannot access a disposed object.\r\nObject name: 'OracleConnection'." 

回答

3

的錯誤說,它的處置對象......這意味着你需要刪除using (條款,這一條款脫手的連接你連接的對象,你不能在using (之外使用這個對象。這意味着如果您希望在外部使用using (,則需要創建新的物體對象。

你可以通過閱讀這篇獲得更多的想法:C# Using Statement

1

至於對方的回答解釋說,該using子句不是天作之合的東西你想再利用。但是我有同樣的想法 - 我仍然希望使用這種模式來自動打開&自動關閉連接。如果這就是你希望做的,那麼關鍵是你正在使用的對象不能是OracleConnection本身,因爲你想要重用這個,而使用它會殺死它。你真的只想要一個新的對象,它在創建時打開連接,並關閉Dispose上的連接,僅此而已。這應該做的伎倆(我用它爲自己的目的):

internal class OpenedContext : IDisposable 
{ 
    private OracleConnection _connection; 

    public OpenedContext(OracleConnection conn) { 
     _connection = conn; 
     if (_connection.State != System.Data.ConnectionState.Open) _connection.Open();    
    } 

    public void Dispose() { 
     if (_connection.State != System.Data.ConnectionState.Closed) _connection.Close(); 
    } 

} 

,然後在例如,你可以這樣做......

  // Early on... 
      OracleConnection _connection = DbConnectionsManager.GetDatabaseConnection(aDbConnectionString); 

      // ... Later on, in various other calls ... 
      using (new OpenedContext(_connection)) 
      { 
       OracleCommand command = _connection.CreateCommand(); 
       string sql = "SELECT * FROM MYTABLE"; 
       command.CommandText = sql; 
       OracleDataReader reader = command.ExecuteReader(); 
       while (reader.Read()) 
       { 
        string myField = (string)reader["EXAMPLE"]; 
        Console.WriteLine(myField); 
       } 
      } 

雖然這是一個愚蠢的方式,我絕對更喜歡設置這樣一種模式,以便始終期待未來的編碼人員在每次數據庫調用時手動「包裝」重新打開的重新關閉的&。它更具可讀性(或可忽略性),風險較小(如果您非常擔心閒置時關閉連接)。