プロジェクトで Dapper を使い始めたばかりで、過去数年間は NHibernate や EF などの ORM を主に使用していました。
通常、Web アプリケーションでは、リクエストごとにセッションを実装し、リクエストの開始時にトランザクションを開始し、最後にコミットします。
SqlConnection / System.Transactions を直接操作する場合、同様のことを行う必要がありますか?
StackOverflow はどのようにそれを行いますか?
解決
@gbn と @Sam Safron の両方のアドバイスを受けて、私はトランザクションを使用していません。私の場合、読み取りクエリのみを実行しているため、トランザクションを使用する必要はないようです (暗黙のトランザクションについて言われたこととは対照的です)。
リクエストごとに接続を使用できるように、軽量のセッション インターフェイスを作成します。Dapper を使用すると、オブジェクトを構築するためにいくつかの異なるクエリを作成する必要があり、むしろ同じ接続を共有したいので、これは私にとって非常に有益です。
リクエストごとに接続をスコープして破棄する作業は、私の IoC コンテナー (StructureMap) によって行われます。
public interface ISession : IDisposable {
IDbConnection Connection { get; }
}
public class DbSession : ISession {
private static readonly object @lock = new object();
private readonly ILogger logger;
private readonly string connectionString;
private IDbConnection cn;
public DbSession(string connectionString, ILogger logger) {
this.connectionString = connectionString;
this.logger = logger;
}
public IDbConnection Connection { get { return GetConnection(); } }
private IDbConnection GetConnection() {
if (cn == null) {
lock (@lock) {
if (cn == null) {
logger.Debug("Creating Connection");
cn = new SqlConnection(connectionString);
cn.Open();
logger.Debug("Opened Connection");
}
}
}
return cn;
}
public void Dispose() {
if (cn != null) {
logger.Debug("Disposing connection (current state '{0}')", cn.State);
cn.Dispose();
}
}
}