I have having trouble understanding the transaction concept of unit of work. I use code like: the unit of work class:
public class UnitOfWork : IDisposable
{
private readonly DbContext _context;
private bool disposed = false;
public UnitOfWork()
{
_context = new ResultsContext();
}
public IRepository<T> GetRepository<T>() where T : class
{
return new Repository<T>(_context);
}
public virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
_context.Dispose();
}
}
disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public Study GetStudyWithAll(string studyUid)
{
ResultsContext context = _context as ResultsContext;
return context.Studies.Where(c => c.StudyUid == studyUid)
.Include(s => s.Tasks.Select(t => t.Plugins))
.Include(s => s.Findings)
.Include(s => s.Patient).FirstOrDefault();
}
public void SaveChanges()
{
if (_context != null)
{
bool saved = false;
do
{
try
{
_context.SaveChanges();
saved = true;
}
catch (DbUpdateException ex)
{
// Get the current entity values and the values in the database
var entry = ex.Entries.Single();
//var currentValues = entry.CurrentValues;
switch (entry.State)
{
case System.Data.EntityState.Added:
// added on client, non in store - store wins
entry.State = System.Data.EntityState.Modified;
break;
case System.Data.EntityState.Deleted:
//deleted on client, modified in store
entry.Reload();
entry.State = System.Data.EntityState.Deleted;
break;
case System.Data.EntityState.Modified:
DbPropertyValues currentValues = entry.CurrentValues.Clone();
//Modified on client, Modified in store
entry.Reload();
entry.CurrentValues.SetValues(currentValues);
break;
default:
//For good luck
entry.Reload();
break;
}
}
catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
{
Exception raise = dbEx;
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
string message = string.Format("{0}:{1}",
validationErrors.Entry.Entity.ToString(),
validationError.ErrorMessage);
// raise a new exception nesting
// the current instance as InnerException
raise = new InvalidOperationException(message, raise);
}
}
throw raise;
}
} while (!saved);
}
}
public DbContext Context
{
get { return _context; }
}
}
The way I use it:
using (var uow = new UnitOfWork())
{
//////some stuff///
uow.SaveChanges();
}
The question is: is the unit of work context equals transaction, or do I need to add:
using (TransactionScope transaction = new TransactionScope())
Around it.
I know that the saveChanges is is wrapped with transaction, what I don't know is : is the whole context wrapped in transaction. I mean, can I be sure that the data I read (not save or update) is not changed during the life of the context?