2012-06-27 66 views
7

我正在編寫與以下代碼類似的佈局的DAL對象。爲了顯示設置,我簡化了很多代碼。你應該重用SqlConnection,SqlDataAdapter和SqlCommand對象嗎?

public class UserDatabase : IDisposable 
{ 
    private SqlDataAdapter UserDbAdapter; 
    private SqlCommand UserSelectCommand; 
    private SqlCommand UserInsertCommand; 
    private SqlCommand UserUpdateCommand; 
    private SqlCommand UserDeleteCommand; 

    private System.Data.SqlClient.SqlConnection SQLConnection; 

    public UserDatabase() 
    { 
     this.SQLConnection = new System.Data.SqlClient.SqlConnection(ConnectionString); 
     this.UserDbAdapter= new SqlDataAdapter(); 
     this.UserDbAdapter.DeleteCommand = this.UserDeleteCommand; 
     this.UserDbAdapter.InsertCommand = this.UserInsertCommand; 
     this.UserDbAdapter.SelectCommand = this.UserSelectCommand; 
     this.UserDbAdapter.UpdateCommand = this.UserUpdateCommand; 
    } 

    private bool FillUsers(DataSet UserDataSet, out int numberOfRecords) 
    { 
     bool success = true; 

     numberOfRecords = 0; 
     string errorMsg = null; 

     this.UserDbAdapter.SelectCommand = this.GetUsersSelectCommand(); 

     numberOfRecords = UserDbAdapter.Fill(UserDataSet, UsersTableName); 

     return success; 
    } 

    private SqlCommand GetUserSelectCommand() 
    { 
     if (this.UserSelectCommand==null) 
      this.UserSelectCommand= new System.Data.SqlClient.SqlCommand(); 
     this.UserSelectCommand.CommandText = "dbo.Users_Select"; 
     this.UserSelectCommand.CommandType = System.Data.CommandType.StoredProcedure; 
     this.UserSelectCommand.Connection = this.SQLConnection; 
     this.UserSelectCommand.Parameters.Clear(); 
     this.UserSelectCommand.Parameters.AddRange(new System.Data.SqlClient.SqlParameter[] { 
     new System.Data.SqlClient.SqlParameter("@RETURN_VALUE", System.Data.SqlDbType.Variant, 0, System.Data.ParameterDirection.ReturnValue, false, ((byte)(0)), ((byte)(0)), "", System.Data.DataRowVersion.Current, null)}); 

     return UserSelectCommand; 
    } 

有跡象表明被寫入以相同的方式重複使用的連接對象,SqlCommands和SqlDataAdapter的多個其他填充類型的功能。 SqlDataAdapter在內部管理SqlConnection的打開和關閉。

所以我的問題是多部分。這種設計不好嗎?如果是這樣,爲什麼?

如果它是壞的,應該把它改爲讓事情更局部範圍如下所示:

public bool FillUsers(DataSet UserDataSet) 
    { 
     using (SqlConnection conn = new SqlConnection(ConnectionString)) 
     { 
      using (SqlCommand command = GetUsersSelectCommand()) 
      { 
       using (SqlDataAdapter adapter = new SqlDataAdapter(command, conn)) 
       { 
        adapter.Fill(UserDataSet, UsersTableName); 
       } 
      } 
     } 
    } 

這對所有這似乎是創建,配置的功能來完成,並那麼重建會比保持物品更糟糕。但是,這似乎是我在網上隨處可見的設置。

+0

您是否測量過性能問題,以至於您覺得需要優化?數據庫連接按設計彙集。沒有必要「頂替」。 – spender

+0

我幾年前問過一個類似的問題:http://stackoverflow.com/questions/226127/multiple-single-instance-of-linq-to-sql-datacontext – spender

+0

沒有性能問題關聯。我開始一個新項目,需要一個數據訪問對象,並且好奇這是否「正確」或者是否有更好的方法。 – Equixor

回答

8

不,沒有什麼問題。您應該儘快處置實施IDisposable的對象。

給定SqlConnection,當您處理連接時,底層連接將簡單地返回到池中。不一定像你想象的那樣「封閉」。最好讓連接池做它的工作。 Here是MSDN到ADO.NET連接池的鏈接。試圖讓它做的事情不是爲某些人設計的(有些人稱這種優化令人驚訝)通常是順着兔子洞下去的。

另外,請確保您已經實際測量並觀察了一個問題,然後嘗試對其進行優化。 (我的意思並不是這麼苛刻,只爲了節省你的時間)。

+0

在處理UserDatabase對象之前,頂級代碼不會處理任何對象。所以似乎重用它們會違背這種設計實踐? – Equixor

+0

@Equixor:我更具體地指SqlConnection。你的類名UserDatabase有點誤導,因爲它不是一個真正的數據庫。也許你可以創建一個名爲GetUsers()的方法,它將返回一個用戶列表。你的第二個代碼是正確的。保持它們更糟糕(有時導致難以重現錯誤) –

+0

好的謝謝。我相信這個的整體設計也可以改進。我們擁有的大多數DAL類都是這樣的,並填充BLL隨後使用的數據集。 – Equixor

相關問題