2009-07-12 23 views
2

我已經在一個項目上分配了DAL,其中的DAL由一個基類和函數返回IDataReader,一個Object(int,字符串等)或一個DataSet組成。 ExecuteNonQuery函數也存在。此DAL僅訪問USPs(SQL Server),並使用MS的SqlHelper執行查詢。下面是兩個示例函數從基:在調用ExecuteReader時從基本DAL類處理SqlConnection

protected IDataReader ExecuteReader(string storedProcedure, params object[] parameterValues) 
    { 
     SqlConnection HConnection = new SqlConnection(myConnString); 
     IDataReader ret = null; 
     try 
     { 
      ret = SqlHelper.ExecuteReader(HConnection, storedProcedure, parameterValues); 
     } 
     catch (Exception ex) 
     { 
      HanldeError(ex, storedProcedure, parameterValues); 
     } 
     return ret; 
    } 

    protected object ExecuteScalar(string storedProcedure, params object[] parameterValues) 
    { 
     using (SqlConnection HConnection = new SqlConnection(myConnString)) 
     { 
      object ret = null; 
      try 
      { 
       ret = SqlHelper.ExecuteScalar(HConnection, storedProcedure, parameterValues); 
      } 
      catch (Exception ex) 
      { 
       HanldeError(ex, storedProcedure, parameterValues); 
      } 
      return ret; 
     } 
    } 

其他類從這個基類派生,創建特定任務的DAL類,例如:

public class Orders : BaseDal { 
    public IDataReader GetOrdersList(int clientId, int agentId) 
    { 
     return ExecuteReader("usp_Orders_GetOrdersList", clientId, agentId); 
    } 
    ... 
} 

然後,有調用DAL功能BLL類,並填寫基於來自IDataReader的對象讀取數據的數據對象(例如Order對象):

​​

我的問題是這樣的 - 如果你會看所採取的代碼從BaseDal中,你會注意到只有ExecuteScalar實際上終止了SqlConnection對象(using語句) - 這就是我所有函數的情況。使用ExecuteReader我無法做到這一點,因爲我返回一個開放的SqlDataReader對象,關閉連接將使讀者無效。 我有所有代碼從DAL獲取和使用IDataReader使用using語句,但也是SqlConnection對象被處置,或者是在晚些時候被GC處理,通過不釋放它來傷害連接池早?如果是這樣,這怎麼處理?

另外,是否有更好的方法來創建一個DAL比上面描述的?我不關心數據存儲不可知的DAL,我們只需要一個堅實而容易維護的數據存儲區,一個可以從多個線程獲取許多併發連接。

在此先感謝您的幫助。

回答

4

SqlDataReader如果您在執行命令時指定了CommandBehavior.CloseConnection,將關閉連接。不過,無論如何,這感覺有點難看。

反而,將SqlConnection轉換爲的方法和使用。然後調用者控制何時處置。或者,使用打開的閱讀器執行Action<SqlDataReader>,並在執行操作後使方法關閉閱讀器和連接。當然,這一行動將不得不爲讀者做所需的一切。

+0

謝謝。儘管你認爲這個「醜陋」,但使用`CommandBehavior.CloseConnection`似乎是我最好的選擇,因爲這是SqlHelper在傳遞連接字符串時(而不是`SqlConnection`對象)在內部執行的操作。將`SqlConnection`傳入方法不是一種選擇,因爲它會與我試圖保留的DAL/BLL分離相抵觸。我不熟悉的`Action `方法,但是看起來有點痛苦。只是爲了確保 - 你能指點我一個好地方,看看究竟是什麼意思嗎? – synhershko 2009-07-13 20:39:33