2009-07-10 10 views
3

私が作成する必要がある場合は、私はなど、C#の - 一般的なデータベース接続のためのクラス、コマンド、リーダー

を、接続を作成するコマンドを実行し、データを取得するために、任意のデータベース技術を扱うことができるクラスを設計していたと.net抽象クラス/インタフェースは、{DbConnection、DbCommand、DbParameter、...}または{IDbConnection、IDbCommand、IDbParameterなどを使用する必要があります(SQL Server、Oracle、FireBirdなどのような)既存のRDBMS ...}?

は私が

public bool CreateConnection(DatabaseTypeEnum type) 
{ 
    DbConnection conn ; 

    if(type==DatabaseTye.Oracle) 
    { 
     //.... 
    }  
} 

public DbDataReader GetData() 
{ 

    DbCommand comm; 
    //... 
} 

または、

public bool CreateConnection(DatabaseTypeEnum type) 
{ 
    IDbConnection conn ; 

    if(type==DatabaseTye.Oracle) 
    { 
     //.... 
    } 
} 

public IDbDataReader GetData() 
{ 

    IDbCommand comm; 
    //... 
} 

そして、なぜのようなコードを使用する必要がありますか?

+0

あなたは質問するのが大事ですか:いつジェネリックを作成する必要がありますか?なぜ? –

+0

更新された質問をご覧ください。 –

+0

C#について話すときには、「Generic」という単語の使用に注意してください。この質問には関係のない非常に特殊な意味があります。 – CaptainCasey

答えて

5

あなたがそれを行うときは、[開く閉じる原則に違反しようとしているErmm ...全く別の質問:)

OK、どちらも...

...その特定のスイッチ/ if文場所は私を不快にさせています:)。

私は実際の作成をFactoryクラスに任せて、SQL ServerやDB2、Oracleなどと話しているかどうかは気にしないでください。

理想的には、コードはIDbConnection、IDbCommandなど、または抽象基本クラス(DbConnection、DbCommandなど)とのみ対話する必要があります。場合によっては、特定のプロバイダ(特定のメソッドを使用するためのSqlDataReaderなど)にアップキャストする必要があることがありますが、これはまれです。

ファクトリはこのスイッチ/ if文を1か所にカプセル化して、簡単にメンテナンスできるようにします。実際の作成をapp.configでさらに抽象化することができます。だからapp.configでは、あなたがサポートしているDBバックエンドのタイプを選択すると、そこからファクトリがそれを取り出して必要なDBを作成します。

参照:this。 DbProviderFactoryと接続パートの作成について読む...

+0

+1私から。工場では、接続文字列のproviderNameを使用して、パラメータ接頭辞などのプロバイダ固有のもの(たとえば、MSSQLの場合は「@」、Oracleの場合は「:」など)のproviderSettingsにマッピングします。 – devstuff

0

なぜジェネリックを使用しないのですか?

あなたは、例えば、このようなあなたのクラスを定義することができます:私はにし、維持するために、その本当に簡単に何をすべきか

public class DBHelper<T, Y, W> where T: DbConnection, new() where Y : DbCommand, new() 
{ 
     private T conn_ = new T(); 
     private Y comm_ = new Y();    
} 

だこと。

+0

これはどのようにして実際のコードで動作しますか、それについて解説できますか? – theJerm

+0

DbCommandはconn.CreateCommand()のような接続オブジェクトからインスタンス化できるため、ここではY型のパラメータは必要ありません。また、W型のパラメータは何ですか? – nawfal

0

異なるデータベース・ベンダーが(自分のADO.NETの事のための)インタフェースの異なる実装を持つことになりますので、あなたはIDbConnectionIDbCommandを使用する必要がありますが、あなたが投稿したとおりには良くありません。汎用クラスIDbConnectionIDbCommandをサポートするように、クラス全体を汎用クラスにする必要があります。このようなことがあります。

public class Db<T> where T : IDbConnection, new() 
{ 
    public bool CreateConnection() 
    { 
     T conn; 

     //now you dont need these lines since you dont have to worry about 
     //what type of db you are using here, since they all implement 
     //IDbConnection, and in your case its just T. 
     //if(type==DatabaseTye.Oracle) 
     //{ 
      //.... 
     //} 
    } 

    public DbDataReader GetData() 
    { 
     //get comm object from S conn 
     using(var conn = new S()) 
      using (var comm = conn.CreateCommand()) 

     //... 
    } 

利点は、あなたがこのクラスにはMySQL .NETのコネクタとOracleのいずれかの異なるものになりますDbConnectionDbCommandに使用する型を渡すことができるということです。だから、あなたはクラスの外からいくつかの種類のコントロールを持っています。基本的な実装については、question and my answerを参照してください。

関連する問題