Enterprise Library を標準の DAL として使用しています。それでは、Dapper のメリットを享受したいと思います。実装を見ると、接続クラスを拡張しているだけです。
Enterprise Library を拡張するように Dapper を設定して、両方の世界を楽しむことは考えられますか? それとも、誰かがすでにこれを作成していますか?
Enterprise Library を標準の DAL として使用しています。それでは、Dapper のメリットを享受したいと思います。実装を見ると、接続クラスを拡張しているだけです。
Enterprise Library を拡張するように Dapper を設定して、両方の世界を楽しむことは考えられますか? それとも、誰かがすでにこれを作成していますか?
はい、それは考えられることであり、かなりうまく機能します。Dapper を使用して一部の古い EntLib コードを補完しており、単純なクエリはすばやく簡単に実行できます。最大の課題は、トランザクションを適切に機能させることでした。使用している EntLib のバージョンについては言及していませんが、4.0 以降では TransactionScopes 内で接続を管理するため、EntLib を使用してスコープ内で Dapper の別の接続を開こうとすると、軽量のローカル トランザクションから DTC に自動的にエスカレートします。 (分散トランザクション コーディネーター)。EntLib は、現在開いている接続を取得する方法を実際には提供していないため、Database クラスから派生させて、GetOpenConnection メソッドを公開する必要があります。
public class EntLibDatabaseWrapper : Database
{
// ...Constructor and overrides...
public IDbConnection GetMyOpenConnection()
{
var connectionWrapper = GetOpenConnection();
return connectionWrapper.Connection;
}
}
次に、次のように使用します。
var db = DatabaseFactory.CreateDatabase();
var dbWrapper = new EntLibDatabaseWrapper(db.ConnectionString, db.DbProviderFactory);
using (var scope = new TransactionScope())
{
var connection = dbWrapper.GetMyOpenConnection();
try
{
// Insert a test value using dapper
var fooId =
connection.Query<int>("insert into Foo values (name = @name); select cast(scope_identity() as int",
new { name = "Foo" }).Single();
// Insert a test value using Enterprise Library
var cmd =
db.GetSqlStringCommand(
"insert into Foo values (name = 'Bar'); select cast(scope_identity() as int)");
var barId = int.Parse(db.ExecuteScalar(cmd));
scope.Complete();
}
catch (Exception)
{
connection.Close();
throw;
}
}
より大きなトランザクション スコープがある場合は、各接続を閉じる前に、アクティブなトランザクションにいるかどうかを確認する必要があります。
if(Transaction.Current == null)
connection.Close();
Dapper しか使えないのに、なぜ Enterprise Library を使うのでしょうか? DataSet と DataReader を使用する代わりに、厳密に型指定されたマップされたオブジェクトを返すクエリを実行できます。