Using Unit of Work Pattern with Entity Framework
In a previous
post
I
explained how
to create a
simple repository
on top of
Entity Framework.
In
this post I’ll explain the Unit of Work pattern and
how
we can use it with our data access layer.
What is Unit of Work Pattern?
In his famous and developer
must read book
“Patterns
of Enterprise Application Architecture”, Martin Fowler
defines the Unit of Work as “Maintains a list
of objects affected by a
business transaction and coordinates
the writing out of changes and the
resolution of concurrency
problems.”
What it means is that a unit of work
is a context/session/unit object that
tracks the changes of
business entities during one business transaction. It is
also
responsible for the manage of concurrency problems when they occur.
How to Use The Pattern?
As in the
repository pattern we will start with an interface which was
suggested
by Martin
Fowler:
public interface IUnitOfWork<T>
{
void RegisterNew(T entity);
void RegisterDirty(T entity);
void RegisterClean(T entity);
void RegisterDeleted(T entity);
void Commit();
}
As you can see we register changes of entities inside the unit
of work
and in the end of every transaction we commit it using the commit
method.
In all the major ORMs out there you get all that
functionality within the
session/context objects. It is the unit of work object
that holds the details
of every change you do to an entity. Since this is the case you
don’t
have to have all the four register methods when you use frameworks
like Entity Framework, NHibernate
or other ORMs.
In my example I’m going to use the following unit of work
interface:
public interface IUnitOfWork<T>
{
void RegisterNew(T entity);
void RegisterDeleted(T entity);
void Commit();
}
Entity Framework Example
Lets return to the example of the repository I used
in the previous
post.
I can transform the DepartmentRepository that I’ve built into a
unit of work that handle departments like this
one:
public class DepartmentRepository : IRepository<Department>,
IUnitOfWork<Department>, IDisposable
{
#region Members
private SchoolEntities _context;
#endregion
#region Ctor
public DepartmentRepository()
{
_context = new SchoolEntities();
}
#endregion
#region IRepository<Department> Members
public Department GetById(int id)
{
return _context.Departments.
Where(d => d.DepartmentID == id).
FirstOrDefault();
}
public Department[] GetAll()
{
return _context.Departments.ToArray();
}
public IQueryable<Department> Query(Expression<Func<Department, bool>> filter)
{
return _context.Departments.Where(filter);
}
#endregion
#region IUnitOfWork<Department> Members
public void RegisterNew(Department entity)
{
_context.AddToDepartments(entity);
}
public void RegisterDeleted(Department entity)
{
_context.DeleteObject(entity);
}
public void Commit()
{
_context.SaveChanges();
}
#endregion
#region IDisposable Members
public void Dispose()
{
if (_context != null)
{
_context.Dispose();
}
GC.SuppressFinalize(this);
}
#endregion
}
This is a really simple example of how to implement the pattern.
There are a lot of other examples in the web like in the following
link:
Entity
Framework 4.0 Beta 1 – POCO, ObjectSet, Repository and UnitOfWork
Summary
Lets sum up, every ORM that respect itself (like Entity
Framework) includes
implementation for the unit of work pattern. If
we want to add our abstraction
layer which include a unit of work then we need
to create our implementation.
We will start with an interface such as the one that Martin
Fowler suggested.
Then it is our responsibility to track changes and to persist all
the work that was
done in a time period as a transaction and also manage concurrency
issues.
- Login or register to post comments
- 11511 reads
- Printer-friendly version
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)



