How to implement the scheme of work with Dapper?

I'm currently trying to use Dapper ORM with the Unit Work + Repository template.

I want to use Unit of Work, rather than a simple Dapper repository because my insert and updates require some degree of transaction processing. I could not find any useful examples, since most of them seem to use the Entity Framework and have problems with leakage within the Unit of Work.

Can someone point me in the right direction?

+13
unit-of-work repository-pattern dapper
Jul 08 '15 at 16:18
source share
1 answer

This git project is very useful. I started from the same and made some changes according to my need.

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(); } 

Your repositories should now accept this UnitOfWork in some way. I choose Injection Dependency with constructor.

 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, .........); } } 

And then you call it like this:

With 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; } } 

Without transaction:

 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); } 

Note that UnitOfWork is larger than DBTransaction.

More information about the repository in the above code can be found here .

I already posted this code here . But this question is more appropriate for me for this code; so I am sending a message instead of a link to the original answer.

+8
Jul 11 '17 at 8:44
source share



All Articles