実際に 2 つの DAL をコーディングせずに、この DB 不可知性を実現する良い方法は何ですか? これには、データ アクセス アプリケーション ブロックが適していると聞きました。
8 に答える
NHibernate などのさまざまな ORM ライブラリを調べることもできます。複数のデータベースをターゲットにしている場合は、構成ファイルまたはコードからデータベースを作成できるツールを探すのが最善です。これにより、MySQL と MSSql で同一のデータベースを作成する必要がなくなります。
1つのオプションは、System.Data.SqlClientのSQL Server固有のクラス(SqlConnection、SqlCommand)または対応するMySQL固有のクラスではなく、System.Data名前空間のIDbConnection、IDbCommandなどのクラスを使用してコーディングすることです。使用している特定のデータベースの接続クラスのインスタンスを作成する必要がありますが、そこからは汎用インターフェースを使用できます。
http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/1175d7ea-f5b4-442f-9155-08bf8b2ba06c/およびhttp://www.15seconds.com/issue/040127.htmにいくつかのサンプルコードがあります。
ORMフレームワークは、RDBMSに依存しないインフラストラクチャを実現するのに役立ちますが、UDFとストアドプロシージャを使用している場合は、DALを分離しておく必要があります。結果として、トリガー、T-SQL、ビューの更新、CLRでホストされるC#コードはおそらく使用しません。エンティティとオブジェクトをマップするだけです。
ADO.NETは、ほとんどのプロジェクトで正常に機能します。MSSQLまたはMySQLを切り替える必要がある場合は、次のようにプロバイダーに依存しないアクセスを非常に簡単に実現できます。
private static DbProviderFactory _provider = DbProviderFactories.GetFactory(WebConfigurationManager.ConnectionStrings["database"].ProviderName);
private static string _connectionString = WebConfigurationManager.ConnectionStrings["database"].ConnectionString;
public static DbParameter CreateParameter(string name, object value)
{
DbParameter parameter = _provider.CreateParameter();
parameter.ParameterName = name;
parameter.Value = value;
return parameter;
}
public static DataTable SelectAsTable(string query, DbParameter[] parameters)
{
using (DbConnection connection = _provider.CreateConnection())
{
connection.ConnectionString = _connectionString;
using (DbDataAdapter adapter = _provider.CreateDataAdapter())
{
adapter.SelectCommand = connection.CreateCommand();
adapter.SelectCommand.Parameters.AddRange(parameters);
adapter.SelectCommand.CommandText = query;
DataTable table = new DataTable();
adapter.Fill(table);
connection.Close();
return table;
}
}
}
これを行うための最良の方法(そして実際にはほとんどすべてのデータベースアクセス層)は、O/RMツールを使用することです。私はnHibernateのラッパーであるActiveRecordを好みます...
ARを使用したもののサンプルソースコードを次に示します。Stackedの演算子オブジェクトへのコード
MySQL用のADODB抽象化ライブラリを使用します。ネイティブMySQLライブラリ呼び出しはかなり醜く原始的であるため、いずれにせよ、おそらくより高いレベルのものが必要になります。
.netプロバイダー モデルは、この問題に対処するために特別に設計されています。すべてのデータベース インタラクションを処理し、適切に設計された基本クラスから派生した「プロバイダー」クラスを提供することで、バックエンド プロバイダー (sql、mySql (blech)、xml など) を最小限の労力で交換できます。
また、私の経験では、ORM で生成されたコードは、有能な開発者が作成したコードと競合することはできず、多くの場合、ORM によって解決されるメンテナンスの問題がさらに発生します。ORM は、SQL のインとアウトに不慣れな人にのみ必要な、より低速でリソースを大量に消費するコードに貢献する、もう 1 つの抽象化レイヤーです。
ERD 作図ツールを使用して純粋に論理的な設計を構築し、オプションごとに DDL を生成します。
あなたはDBDesignerをチェックアウトするかもしれません...
他の人が指摘したように、関連する実際のクラスから自分自身を抽象化してみてください。これには、AHd54 が指摘するように、インターフェイスの使用、または同様のものが含まれます。
ただし、それでは道半ばになります。
実行する必要がある SQL にも、次のような違いがあります。
- パラメータ名の構文
- 位置パラメーターと名前付きパラメーター
- 関数名
- 最初の N 行のみを指定する方法など、いくつかの構文の違い
これらすべてをカバーする必要があり、ORM を使用できない、または使用しない場合 (ただし、100% 達成されることはめったにありません)、1 つの方法は、関連する実際のクラスだけでなく抽象化する独自のクラスを作成することです。だけでなく、コードの違いを処理するために何らかのタイプの SQL 書き換えも行います。
私は書き直しの道をたどったので、それについての指針が必要な場合は、この回答に質問を付けてコメントを追加してください。それに応じて回答を更新します。