2014-10-20 58 views
0

細節 - 我在C#中的SQL數據庫傭工的方法(如下面),它建立了一個連接數據庫連接的生命週期對象

public void EstablishConnection() 
    { 

     oConnection = oFactory.CreateConnection(); 

     if (oConnection.State == ConnectionState.Closed) 
     { 
      oConnection.ConnectionString = StringConnection; 
      oConnection.Open(); 
      oConnectionState = ConnectionState.Open; 
     } 
    } 

對於作出分貝像(的ExecuteNonQuery等),這是任何方法調用典型的方法如何看起來像

public DataSet DataAdapter(CommandType cmdType, string cmdText, Parameters[] cmdParms) 
    { 

     DbDataAdapter dda = null; 
     try 
     { 
      EstablishFactoryConnection(); 
      dda = oFactory.CreateDataAdapter(); 
      PrepareCommand(false, cmdType, cmdText, cmdParms); 

      dda.SelectCommand = oCommand; 
      DataSet ds = new DataSet(); 
      dda.Fill(ds); 
      return ds; 
     } 
     catch (Exception ex) 
     { 
      throw ex; 
     } 
     finally 
     { 
      if (null != oCommand) 
       oCommand.Dispose(); 
      CloseFactoryConnection(); 
     } 
    } 

和CloseFactoryConnection();方法是像下面

public void CloseFactoryConnection() 
    { 
     //check for an open connection    
     try 
     { 
      if (oConnection.State == ConnectionState.Open) 
      { 
       oConnection.Close(); 
       oConnectionState = ConnectionState.Closed; 
      } 
     } 
     catch (DbException oDbErr) 
     { 
      //catch any SQL server data provider generated error messag 
      throw new Exception(oDbErr.Message); 
     } 
     catch (System.NullReferenceException oNullErr) 
     { 
      throw new Exception(oNullErr.Message); 
     } 
     finally 
     { 
      if (null != oConnection) 
       oConnection.Dispose(); 
     } 
    } 

問題 - 我有這個類(DBHelper)在我所有的倉庫,它的IOC容器構造注入這個被使用。這些實例的生活方式是HttpContextLifecycle(我正在使用Structuremap,它說這種生活方式意味着將爲每個HttpContext創建一個單一實例,並在HttpContext.Items集合中緩存實例。)

這是正確的TYPE我正在使用的db連接類的生活方式?

創建連接/打開/關閉它的類應該作爲單例實例化嗎?或每個請求?

這些db連接建立類的普遍接受的生活方式是什麼?我正在使用ado.net,沒有ORM。

感謝

回答

2

因爲ADO.NET已經使用連接池,沒有必要緩存/重用DbConnection實例。考慮到這一點,你的類似乎不會添加任何有用的東西,而不是簡單地寫出代碼 - 你抽象出來的唯一東西是連接字符串,並且通過使其可配置(ConnectionStrings["DatabaseName"])來充分處理。

除了缺乏附加值,您的班級還有其他問題。捕捉NullReferenceException是一個很大的禁忌 - 一個NullReferenceException表明你的代碼中存在一個嚴重的錯誤,應該通過調查崩潰來修復,而不是將它作爲另一個異常封裝(當你打包時,不要使用Exception,因爲它是非特定的客戶不能抓住一切,這是另一件壞事)。更重要的是,當然,應該由null適當檢查防止(見What is a NullReferenceException, and how do I fix it?

要知道爲什麼你的類可能是沒有用的,考慮CloseFactoryConnection可以簡化爲沒有丟失任何功能如下:

public void CloseFactoryConnection() { 
    using (oConnection) { } 
} 

這樣一來就給了廣闊的回答你的問題:如果你不使用ORM,你可能不希望一類建立在所有的數據庫連接,超越你已經得到的人。如果您想使用依賴注入來獲取數據,請不要在此級別使用它,但是在對象級別 - 您希望能夠抽象出使用數據庫的全部內容,而不僅僅是從如何創建DataSet

+0

感謝您的回覆。我把這個放在了船上,但是這是一些遺留的代碼,我無法刪除(因爲它被徹底使用)。你如何看待實例化對象的生活方式?如果我想用這種方式處理數據庫連接等問題?你認爲每個請求是否合適? – 2014-10-20 13:27:26

+0

如果這個類是一個給定的,並且你必須決定什麼時候實例化它,那麼爲了你自己的理智,根據請求做出決定。這是因爲像這樣的類表示共享狀態,並且如果狀態實際上根本不共享,那麼對於錯誤的機會最小。正如我所說,任何性能損失都應該可以忽略不計,因爲它實際上並沒有多大作用。 – 2014-10-20 13:43:46