2011-02-17 7 views
3

私はデータアクセスクラスの基本クラスを持っています。このクラスはIDisposableを実装します。この基本クラスにはIDbConnectionが含まれ、コンストラクタでインスタンス化されます。IDbCommandはIDisposableを実装するクラス内から処理されますか?

:FooDALは処分が、このようなコードでFooDALに呼び出されることを保証するために用いたパターンを使用して使用

public class FooDAL : DALBase 
{ 
    public int CreateFoo() 
    { 
     // Notice that the cmd here is not wrapped in a using or try-finally. 
     IDbCommand cmd = CreateCommand("create foo with sql", cn); 
     Open(); 
     int ident = int.Parse(cmd.ExecuteScalar().ToString()); 
     Close(); 
     cmd.Dispose(); 
     return ident; 
    } 
} 

クラス:このクラスから継承し

public class DALBase : IDisposable 
{ 
    protected IDbConnection cn; 
    public DALBase() 
    { 
     cn = new MySqlConnection(connString); 
    } 
    public void Dispose() 
    { 
     if (cn != null) 
     { 
      if (cn.State != ConnectionState.Closed) 
      { 
       try 
       { 
        cn.Close(); 
       } 
       catch 
       { 
       } 
      } 
      cn.Dispose(); 
     } 
    } 
} 

クラスは、実際にデータベースにアクセスします

using(FooDAL dal = new FooDAL()) 
{ 
    return dal.CreateFoo(); 
} 

私の質問は、IDbCommandが使用パターンでラップされていなくても正しく処理されていることを保証しますか?コマンドの実行中に例外が発生した場合はどうなりますか?

また、パフォーマンス上の理由から、基本クラスのコンストラクタではなくCreateFooで接続をインスタンス化する方が良いでしょうか?

何か助けていただければ幸いです。

答えて

1

接続がプールされている場合は、CreateFOOメソッド(usingブロックを使用)でMySqlConnectionを作成してください。

使用ブロックの最後に自動的に廃棄/閉鎖されるため、閉めすぎることはありません。

public int CreateFoo() 
{ 
    using (var cn = new MySqlConnection(connString)) 
    { 
     // Notice that the cmd here is not wrapped in a using or try-finally. 
     using (IDbCommand cmd = CreateCommand("create foo with sql", cn)) 
     { 
      cn.Open(); 
      return int.Parse(cmd.ExecuteScalar().ToString()); 
     } 
    } 
} 
+0

副次的に、IDisposableフィールドを持つクラスがある場合、このクラスもIDisposableでなければなりません(http://msdn.microsoft.com/en-us/library/ms182172%28v=vs.80を参照)。 %29.aspx) – yorah

0

これがすべて効率のために必要な場合は、コードを高速化するためにできる最大の変更は、各DbCommandでdb接続オブジェクトを開いたり閉じたりしないようにすることです。

+0

接続は.Netにプールされているため、Open()を呼び出すと、初めて接続するときにのみ接続が有効に開きます。接続を「開く」ためのコストは、パフォーマンス(ほとんどの場合)に関して重要ではありません。 – yorah

+0

Close()を呼び出すことを除いて、db接続を閉じると仮定します。これを回避するには、DbConnectionのConnectionStateを確認します。 – steinberg

+0

接続でCloseまたはDisposeを呼び出すと、接続がプールに戻されます。 (http://msdn.microsoft.com/en-us/library/8xx3tyca%28v=VS.100%29.aspx)=>これは.Net 1.1から有効です – yorah

関連する問題