2012-06-27 3 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; 
    } 

Connectionオブジェクト、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()という名前のメソッドを作成すると、ユーザーのリストが返されます。 2番目のコードポストは正しいものです。それらを維持することは悪いです(そして時にはバグを再現するのが難しくなります) –

+0

ありがとうございます。私はこれの全体的なデザインも改善できると確信しています。私たちが持っているほとんどのDALクラスは、このようなもので、BLLによって使用されるデータセットを埋めます。 – Equixor

関連する問題