如何用Dapper实现工作单元模式?
目前,我正在尝试使用工作单元+库模式的Dapper ORM。
我想使用工作单元而不是简单的精简库,因为我的插入和更新需要一定程度的事务处理。 我一直无法find任何有用的例子,因为大多数似乎使用entity framework,并在工作单位内泄漏问题。
有人能指点我的方向吗?
这个Git项目是非常有帮助的。 我从同样的方式开始,根据我的需要做了一些改变。
public sealed class DalSession : IDisposable { public DalSession() { _connection = new OleDbConnection(DalCommon.ConnectionString); _connection.Open(); _unitOfWork = new UnitOfWork(_connection); } IDbConnection _connection = null; UnitOfWork _unitOfWork = null; public UnitOfWork UnitOfWork { get { return _unitOfWork; } } public void Dispose() { _unitOfWork.Dispose(); _connection.Dispose(); } } public sealed class UnitOfWork : IUnitOfWork { internal UnitOfWork(IDbConnection connection) { _id = Guid.NewGuid(); _connection = connection; } IDbConnection _connection = null; IDbTransaction _transaction = null; Guid _id = Guid.Empty; IDbConnection IUnitOfWork.Connection { get { return _connection; } } IDbTransaction IUnitOfWork.Transaction { get { return _transaction; } } Guid IUnitOfWork.Id { get { return _id; } } public void Begin() { _transaction = _connection.BeginTransaction(); } public void Commit() { _transaction.Commit(); Dispose(); } public void Rollback() { _transaction.Rollback(); Dispose(); } public void Dispose() { if(_transaction != null) _transaction.Dispose(); _transaction = null; } } interface IUnitOfWork : IDisposable { Guid Id { get; } IDbConnection Connection { get; } IDbTransaction Transaction { get; } void Begin(); void Commit(); void Rollback(); }
现在,你的仓库应该以某种方式接受这个UnitOfWork。 我用构造函数select了dependency injection。
public sealed class MyRepository { public MyRepository(IUnitOfWork unitOfWork) { this.unitOfWork = unitOfWork; } IUnitOfWork unitOfWork = null; //You also need to handle other parameters like 'sql', 'param' ect. This is out of scope of this answer. public MyPoco Get() { return unitOfWork.Connection.Query(sql, param, unitOfWork.Transaction, .......); } public void Insert(MyPoco poco) { return unitOfWork.Connection.Execute(sql, param, unitOfWork.Transaction, .........); } }
然后你这样称呼它:
交易:
using(DalSession dalSession = new DalSession()) { UnitOfWork unitOfWork = dalSession.UnitOfWork; unitOfWork.Begin(); try { //Your database code here MyRepository myRepository = new MyRepository(unitOfWork); myRepository.Insert(myPoco); //You may create other repositories in similar way in same scope of UoW. unitOfWork.Commit(); } catch { unitOfWork.Rollback(); throw; } }
无交易:
using(DalSession dalSession = new DalSession()) { //Your database code here MyRepository myRepository = new MyRepository(dalSession.UnitOfWork);//UoW have no effect here as Begin() is not called. myRepository.Insert(myPoco); }
请注意,UnitOfWork不仅仅是DBTransaction。
上面代码中有关Repository的更多细节可以在这里find。
我已经在这里发布这个代码。 但是这个问题在这个代码中看起来与我更相关。 所以我再次发布,而不是只是链接到原来的答案。