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