Я только начал использовать Dapper для проекта, в течение последних нескольких лет в основном использовал ORM, такие как NHibernate и EF.
Как правило, в наших веб-приложениях мы реализуем сеанс по запросу, начиная транзакцию в начале запроса и фиксируя ее в конце.
Должны ли мы делать нечто подобное при работе напрямую с 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();
}
}
}