我刚刚开始在一个项目中使用 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();
}
}
}