8

次のコードのようなレイアウトで記述された DAL オブジェクトを使用しています。セットアップを示すためだけに、多くのコード コードを単純化しました。

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 を再利用して同じ方法で記述された Fill タイプの関数が他にも複数あります。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);
                }
            }
        }
    }

これは、作成、破棄、および再作成のように見えるすべての機能に対して実行する必要があり、アイテムを保持するよりも悪いでしょう。ただし、これはオンラインのどこでも見られる設定のようです。

4

1 に答える 1

8

いいえ、何も問題はありません。実装するオブジェクトは、使いIDisposable終わったらすぐに破棄する必要があります。

を指定すると、接続を破棄SqlConnectionすると、基礎となる接続が単にプールに返されます。あなたが思うかもしれないように、必ずしも「閉じている」わけではありません。接続プールにその仕事を任せるのが最善です。 これは、MSDN のADO.NET接続プールへのリンクです。設計されていないことを実行しようとすると (驚くべきことに、これを最適化と呼ぶ人もいます)、通常、うさぎの穴を下る旅になります。

また、最適化を試みる前に、問題を実際に測定して観察したことを確認してください。(これは厳しい意味ではありません。時間を節約するためだけです)。

于 2012-06-27T23:39:14.230 に答える