DCSIMG
Revisiting the Repository and Unit of Work Patterns with Entity Framework - Gil Fink's Blog

Gil Fink's Blog

Fink about IT

News

Microsoft MVP

My Facebook Profile My Twitter Profile My Linkedin Profile

Locations of visitors to this page

Creative Commons License

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.
© Copyright 2013 Gil Fink

Hebrew Articles

Index Pages

My OSS Projects

English Articles

Revisiting the Repository and Unit of Work Patterns with Entity Framework

Revisiting the Repository and Unit of Work Patterns with Entity Framework

In the past I wrote twoRevisiting the Repository and Unit of Work Patterns with Entity Framework
posts about the
Repository and the
Unit of Work patterns
(here and here). Today
I want to show a better
and less naive solution
for imposing the Unit of Work and the Repository patterns with
Entity Framework.

Revisiting The Repositoy Implementation

In the Repository pattern, I added to the interface two new
methods for adding and removing an entity:

public interface IRepository<T>
                where T : class
{
  T GetById(int id);
  IEnumerable<T> GetAll();
  IEnumerable<T> Query(Expression<Func<T, bool>> filter);    
  void Add(T entity);
  void Remove(T entity);
}

Also I’ve changed the return type of the Query from IQueryable
to IEnumerable in order not to enable additional composition
on that query that will hit the database.
The implementation of the Repository itself will change as follows:

public abstract class Repository<T> : IRepository<T>
                                  where T : class
{
  #region Members
 
  protected IObjectSet<T> _objectSet;
 
  #endregion
 
  #region Ctor
 
  public Repository(ObjectContext context)
  {
    _objectSet = context.CreateObjectSet<T>();
  }
 
  #endregion
 
  #region IRepository<T> Members
 
  public IEnumerable<T> GetAll()
  {
    return _objectSet;
  }
 
  public abstract T GetById(int id);
 
  public IEnumerable<T> Query(Expression<Func<T, bool>> filter)
  {
    return _objectSet.Where(filter);
  }
 
  public void Add(T entity)
  {
    _objectSet.AddObject(entity);
  }
 
  public void Remove(T entity)
  {
    _objectSet.DeleteObject(entity);
  }
 
  #endregion

One of the things to notice is that I hold an IObjectSet as my data 
member of the Repository itself instead of holding the context like
in my previous post. The IObjectSet is a new interface in EF4
which helps to abstract the use of the created entity sets.
Now the Repository is better implemented and looks like an
in-memory collection as it was suppose to be. If I need more specific
methods I can inherit from this Repository implementation and add the
desired functionality. As you can see I don’t implement the GetById
method and enforce my concretes to implement it.
The DepartmentRepository from the previous post will look like:

public class DepartmentRepository : Repository<Department>
{
   #region Ctor
 
   public DepartmentRepository(ObjectContext context)
     : base(context)
   {
   }
 
   #endregion
 
   #region Methods
 
   public override Department GetById(int id)
   {
     return _objectSet.SingleOrDefault(e => e.DepartmentID == id);
   }
 
   #endregion
}

Revisiting The Unit of Work Implementation

After we have our Repository we would like to create a
Unit of Work to hold the application repositories and to
orchestrate the persisting of data for some business transactions.
The new interface for the Unit of Work will look like:

public interface IUnitOfWork
{
  IRepository<Department> Departments { get; }    
  void Commit();
}

By of course if you have more repositories in your application you
will add them to the IUnitOfWork (in the example I only have the
departments repository). Now the implementation of the Unit of Work
won’t be a part of the repository (like in the old post) and will look like:

public class UnitOfWork : IUnitOfWork
{
  #region Members
 
  private readonly ObjectContext _context;
  private DepartmentRepository _departments;
 
  #endregion
 
  #region Ctor
 
  public UnitOfWork(ObjectContext context)
  {
    if (context == null)
    {
      throw new ArgumentNullException("context wasn't supplied");
    }
 
    _context = context;
  }
 
  #endregion
 
  #region IUnitOfWork Members
 
  public IRepository<Department> Departments
  {
    get
    {
      if (_departments == null)
      {
        _departments = new DepartmentRepository(_context);
      }
      return _departments;
 
    }
  }
 
  public void Commit()
  {
    _context.SaveChanges();
  }
 
  #endregion
}

As can be seen the Unit of Work holds the ObjectContext but
you could use an IContext interface instead if you like to be more
abstract and with no dependency on Entity Framework at all. This can be
achieved by using the T4 templates that were provided in EF4 which you
will use to add the IContext interface implementation. The
Unit of Work has a constructor that can be injected using an IoC container.
The testing program will change into:

using (SchoolEntities context = new SchoolEntities())
{
  UnitOfWork uow = new UnitOfWork(context);
  foreach (var department in uow.Departments.GetAll())
  {
    Console.WriteLine(department.Name);
  }
 
  foreach (var department in uow.Departments.Query(d => d.Budget > 150000))
  {
    Console.WriteLine("department with above 150000 budget: {0}",
        department.Name);
  }
}

Some thing to notice here is that I create the context during
the running of the program. As I wrote earlier, this can be changed
to using an IoC container instead which will inject the constructor
dependency.

Summary

Lets sum up, this offered solution is much better then the naive
example I gave in the previous posts. It is much more testable and
abstract and as I wrote you could go further and use an IoC container
to inject the use of Entity Framework in the Unit of Work
implementation.

Comments

DotNetKicks.com said:

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# June 21, 2010 7:57 AM

Revisiting the Repository and Unit of Work Patterns with Entity … | Programming Blog Imagik.org said:

Pingback from  Revisiting the Repository and Unit of Work Patterns with Entity &#8230; | Programming Blog Imagik.org

# June 21, 2010 11:44 AM

James Alexander said:

Gil,

This is definitely one of the better suggestions I've seen for incorporating UoW, Repository and EF. One question I have though is how you'd recommend using this pattern along with eager loading in EF. For instance, if I have a type called Department with a collection or navigation property for Employees and want to get the instances of Department that has Employee's with a salaray > $100K, how would you incorporate that functionality.

Also lets say Department has a navigation property called Status and references a table with enum values.

In most instances I want Status eagerly loaded so I'm only issuing one request to my DB server instead of lazy-loading it and issuing a second request. How would you incorporate eager loading into your UoW/Repository pattern?

# June 21, 2010 9:04 PM

Diego said:

This way when Instantiating a unit of work I wouldn't be creating all repositories of my application? This isn't a bad thing thinking in performance?

Please correct me if I'm wrong :)

# June 21, 2010 11:28 PM

Gil Fink said:

@Diego,

The use of Lazy Load to create the repositories when they are needed isn't a bad thing when thinking about performance. I create the resource (repository) when I need it and therefore save memory and time since I won't create a resource that I'm not using. It can impact the performance only when the repository creation is very expensive. In the example, if the CreateObjectSet method is expensive then it will impact the performance of the first operation on the repository.

# June 22, 2010 8:11 AM

Gil Fink said:

@James Alexander,

You can take the solution I offered and manipulate it for your needs. For example, you can create an interface of IDepartmentRepository which will iclude a specific contract for Departments and have a GetDepartmentsAndEmployees method (and also implement the IRepository interface). In the Unit of Work you'll replace the IRepository with the IDepartmentRepository and you will have a solution for your eager loading problem. Of course this is more application specific solution and it is less generic but it still offers the testability of your data access layer.

Another solution will be to create a new method on the IRepository interface like:

IEnumerable<T> QueryObjectGraph(Expression<Func<T, bool>> filter, string children);

In this method implementation you will use the Include method with the supplied children like:

public IEnumerable<T> QueryObjectGraph(Expression<Func<T, bool>> filter, string children)

{

  return _objectSet.Include(children).Where(filter);

}

Pay attention that in this solution you'll have to replace the IObjectSet<T> member to ObjectSet<T> in order to have the Include method implementation.

I hope this is what you seek.

# June 22, 2010 8:46 AM

Gil Fink on .Net said:

Eager Loading with Repository Pattern and Entity Framework One question that I received yesterday after

# June 22, 2010 9:11 AM

links for 2010-06-22 | The Gryphin Experience said:

Pingback from  links for 2010-06-22 | The Gryphin Experience

# June 22, 2010 11:03 PM

Andrew Hay said:

I wrote a quick ASP.Net MVC 2 app using your idea. It turns out that I needed to call .GetAll().ToList() to use the data in my strongly typed view.

I expected the IEnumerable type to take care of this for me, but it's acting like the type is IQueryable and failing because "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection."

Here's what I did:

public ActionResult Index()

{

  IEnumerable<Order> list;

  using (var context = new NorthwindEntities())

  {

     var uow = new UnitOfWork(context);

     list = uow.Orders.GetAll(); // fails

     // list = uow.Orders.GetAll().ToList(); // works

  }

  return View(list);

}

What's that all about?

Regards,

Andrew

# June 23, 2010 2:36 AM

Gil Fink said:

@Andrew Hay,

Since I return the ObjectSet (which implement the IQueryable as well) as the IEnumerable the operation against the database is happening only when you use the set (the same happens in LINQ and this is deffered loading feature). For example when you enumerate the collection (or call the ToList method) it will trigger the query to the database. Since the ObjectSet is part of the ObjectContext which is responsible for database connectivity and it is also disposed in your case then you get the exception. The answer to the problem is to make the lifetime of the ObjectContext per request and dispose it when the request ends.

# June 24, 2010 8:09 AM

Edmilson said:

Hi!  very good post,

I'm not sure but in the IUnitOfWork  that <T>  is used for something?

 Now, one dummie question:

In Asp. Net WebForms.

 Update is my question, I take back the entity  from

DB  by the GetByID method, and fill all textboxs of my WebForm to perform the method GetByID I used some Event on my WebForm Page. now I changed some values on the textboxes  and I want give the entity back to DB, so I have this  Update button on my form.  How do I keep the same Context of the UnitOfWork  that toke the entity before give the Commit?

I´ve tryed put the instance of que UnitOfWork at Page Scope instead some Event, but this is not working.

thanks,

Edmilson

# June 26, 2010 5:50 PM

Gil Fink said:

@Edmilson,

The IUnitOfWork isn't generic, the T slipped from my  previous post example (and I removed it now).

For the second question, my recommandetion for the lifetime of a context is per request and I wrote a post about it in the past. Since your update event is a new request to the server you shouldn't save the previous context (context per request). You can use the Attach method of the ObjectContext with the ApplyCurrentValues (in EF4) or ApplyPropertyChanges (in EF1) in order to attach the entity and make is state as changed in order to commit an update.

# June 26, 2010 7:43 PM

Gil Fink on .Net said:

Repository and Unit of Work T4 Template for Entity Framework Two weeks ago I wrote the Revisiting the

# July 5, 2010 2:19 PM

Edmilson said:

Hi Gil,

I´d like  to know if is possible get lazyLoadind benefits  from this aproach, I´ve been looking one way  go get  the one List  or Collection  of the related objects  using  the  GetByID method  but didn´t  yet.

[]´s

Edmilson

# July 17, 2010 6:59 PM

specter said:

Hello, Thanks for your work. I'm working with Visual Studio 2008 and I'd like to know if this pattern will work on entity framework v1.

Thanks in advance.

# August 11, 2010 3:28 PM

Gil Fink said:

@specter,

The code shown here is based on elements that are available in EF4 such as ObjectSet. You still can impose the repository and unit of work in EF1 but that will be harder.

# August 11, 2010 4:03 PM

Dhani said:

Hi Gil,I read on some other post that instead of making Repository as part of UnitOfWork, they tend to make UnitOfWork as part of Repository. What is the design consideration about this ?

# August 20, 2010 9:23 PM

Gil Fink said:

@Dhani,

The Unit of Work pattern is defined as "Maintain a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems." (taken from Martin Fawler's book "Patterns of Enterprise Application Architecture"). The Repository is meant to be an abstraction layer above the data mapping layer (ADO, EF, LINQ to SQL etc). As I see it the unit of work which coordinate the business transactions will use repositories in order to do its work and not the opposite as you indicated.

# August 21, 2010 1:33 PM

Tomas F. said:

Hi Gil,

could you explain me please how to implement the above mentioned IContext interface with dependency injection  for example via IoC? Let's say that:

 protected IObjectSet<T> _objectSet;

 public Repository(IContext context)

 {

   //_objectSet = context.CreateObjectSet<T>();

 }

How to inject both ObjectContext : IContext and MockContext : IContext to the _objectSet variable through constructor injection? My problem is that MockContext doesn't implement CreateObjectSet<T>(), but MockContext contains a private variable IObjectSet<Customer> _customers.

Thank you for your advice, Tomas

# August 31, 2010 12:34 PM

UoW, Repository and EF « smnbss's Blog said:

Pingback from  UoW, Repository and EF &laquo; smnbss&#039;s Blog

# November 11, 2010 11:36 AM

Entity Framework 4 Unit of Work / Repository WITHOUT .Query() Lambda - Programmers Goodies said:

Pingback from  Entity Framework 4 Unit of Work / Repository WITHOUT .Query() Lambda - Programmers Goodies

# July 30, 2011 12:41 AM

Usage of ???Expression<Func>??? - Programmers Goodies said:

Pingback from  Usage of ???Expression&lt;Func&gt;??? - Programmers Goodies

# August 5, 2011 2:32 PM

The Repository Pattern: Links, News and Resources (1) « Angel “Java” Lopez on Blog said:

Pingback from  The Repository Pattern: Links, News and Resources (1) &laquo; Angel &#8220;Java&#8221; Lopez on Blog

# October 7, 2011 12:08 PM

Entity Framework 4 Repository? - Programmers Goodies said:

Pingback from  Entity Framework 4 Repository? - Programmers Goodies

# November 24, 2011 5:21 AM

??????Repository?????? | ????????????????????? said:

Pingback from  ??????Repository?????? | ?????????????????????

# March 6, 2013 4:08 AM