I've created the unitofwork class below:
public class UnitOfWork : IUnitOfWork
{
private AppDbContext _context { get; set; }
private IDbTransaction _transaction { get; set; }
private ObjectContext _objectContext { get; set; }
private bool _isDisposed;
public UnitOfWork(AppDbContext context)
{
_context = context;
}
public DbSet<T> Set<T>() where T : class
{
return _context.Set<T>();
}
public DbEntityEntry<T> Entry<T>(T entity) where T : class
{
return _context.Entry(entity);
}
public void Begin()
{
_objectContext = ((IObjectContextAdapter)_context).ObjectContext;
if (_objectContext.Connection.State != ConnectionState.Open)
{
_objectContext.Connection.Open();
if(_transaction != null)
{
_transaction.Dispose();
}
_transaction = _objectContext.Connection.BeginTransaction();
}
}
public void AutoDetectChangesEnabled(bool option)
{
_context.Configuration.AutoDetectChangesEnabled = option;
}
public void LazyLoadingEnabled(bool option)
{
_context.Configuration.LazyLoadingEnabled = option;
}
public void SaveChanges()
{
_context.SaveChanges();
}
public Task SaveChangesAsync()
{
return _context.SaveChangesAsync();
}
public void Commit()
{
_transaction.Commit();
}
public void Rollback()
{
_transaction.Rollback();
foreach (var entry in _context.ChangeTracker.Entries())
{
switch (entry.State)
{
case System.Data.Entity.EntityState.Modified:
entry.State = System.Data.Entity.EntityState.Unchanged;
break;
case System.Data.Entity.EntityState.Added:
entry.State = System.Data.Entity.EntityState.Detached;
break;
case System.Data.Entity.EntityState.Deleted:
entry.State = System.Data.Entity.EntityState.Unchanged;
break;
}
}
}
public void Dispose()
{
if (!_isDisposed)
{
if (_context != null)
{
_context.Database.Connection.Close();
_context.Dispose();
_context = null;
}
if(_transaction != null)
{
_transaction.Dispose();
_transaction = null;
}
_isDisposed = true;
}
}
}
}
usage
without transaction
_unitOfWork.Set<User>().Add(MyModel);
with transaction
_unitOfWork.Begin();
try {
_unitOfWork.Set<User>().Add(MyModel);
_unitOfWork.SaveChanges();
_unitOfWork.Commit();
}
catch {
_unitOfWork.Rollback();
}
I must close the transaction in dispose? How can I improve this code?
Observation: I'm use DI with IUnitOfWork, use AutoFac
Rollback
? You should dispose the UoW when it isn't committed. \$\endgroup\$