Applying The Repository Pattern on LINQ and ADO.NET Entity Framework 4

Introduction The Repository Design Pattern

The Repository design pattern adds a layer of abstraction on top of the query layer and helps to eliminate duplicate query logic in your application's code. In his great book "Patterns of Enterprise Application Architecture", Martin Fowler defines the Repository Pattern as: "Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects." This article takes a look at the principles of the repository pattern and discusses how it can be implemented in applications that make use of LINQ and the Entity Framework 4.0.

Pre-requisites

To use the code examples illustrated in this article, you should have any one of the following installed in your system:

  • Microsoft Visual Studio 2008
  • Microsoft Visual Studio 2010

What is the Repository Pattern?

A repository is essentially a collection of in memory domain objects. The repository pattern provides a way to provide isolation between the data access layer of your application with the presentation and business layer. In using the repository pattern, you can have persistence, ignorance and a separation of concerns in your data access code. The repository encapsulates the necessary logic to persist your domain objects in the underlying data store. In essence, you can use the repository pattern to decouple the domain model from the data access code.

Martin Fowler states: "A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers." Reference: http://martinfowler.com/eaaCatalog/repository.html

The following code snippet illustrates how a repository interface is designed:

    public interface IStudentRepository
       {
           Student GetByID(int studentID);
           Student Load(int studentID);
           void Save(Student student); 
           void Delete(Student student);
       }
 

Similar to the interface for the Student Repository, you can have interfaces for Product and Order Repositories as shown below:

   public interface IProductRepository
       {
           Product GetByID(int productID);
           Product Load(int productID);
           void Save(Product product); 
           void Delete(Product product);
       }
   
   public interface IOrderRepository
       {
           Order GetByID(int orderID);
           Order Load(int orderID);
           void Save(Order order); 
           void Delete(Order order);
       }
 

You can now use generics to generalize this interface. Here's a generic implementation of the interface for any repositories of this kind.

  public interface IRepository<T>
  {
      T GetById(int id);
      T Load(int id);
      void Save(T entity); 
      void Delete(T entity);
  }

Designing a LINQ Repository

To implement the repository pattern for LINQ, you would first need to define the interface that would contain the declaration of all the methods you would want in your Repository.

The following interface shows how you can use the repository pattern in LINQ:

   public interface IRepository<T> where T : class
       {
           IQueryable<T> GetAll();
           void InsertOnSubmit(T entity);
           void DeleteOnSubmit(T entity);
           void SubmitChanges();
       }
 

You can then use your repository to encapsulate the way storage, retrieval and query would be accomplished in your data access code using the LINQ data context. The IRepository interface is implemented by the repository class as shown in the code listing below:

   public class Repository<T> : IRepository<T> where T : class
       {
           public DataContext Context
           {
               get;
               set;
           }
   
           public virtual IQueryable<T> GetAll()
           {
               return Context.GetTable<T>();
           }
           public virtual void InsertOnSubmit(T entity)
           {
               GetTable().InsertOnSubmit(entity);
           }
           public virtual void DeleteOnSubmit(T entity)
           {
               GetTable().DeleteOnSubmit(entity);
           }
           public virtual void SubmitChanges()
           {
               Context.SubmitChanges();
           }
           public virtual ITable GetTable()
           {
               return Context.GetTable<T>();
          
    }
       }
 



Applying The Repository Pattern on LINQ and ADO.NET Entity Framework 4

Designing a Repository for Entity Framework 4

The ADO.NET Entity Framework is an extended Object Relational Mapping (ORM) that can be used to abstract the object model of an application from its relational or logical model. The ADO.NET Entity Framework was designed by Microsoft to objectify your application's data and in doing so; isolate the logical or relational model of your application from the object model. ADO.NET Entity Framework 4.0 ships with Microsoft Visual Studio 2010 and provides a lot of new features and enhancements.

To implement the repository pattern for Entity Framework, you can start by defining an interface as shown below:

  public interface IRepository&lt;T&gt;
  {
   &nbsp;&nbsp;&nbsp;T GetById(int id);
   &nbsp;&nbsp;&nbsp;T[] GetAll(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
   &nbsp;&nbsp;&nbsp;IQueryable&lt;T&gt; Query(Expression&lt;Func&lt;T, bool&gt;&gt; filter);
   &nbsp;&nbsp;&nbsp;void Save(T entity); 
   &nbsp;&nbsp;&nbsp;void Delete(T entity);
  }

Now that the interface has been defined, you can use it to implement your repository classes. The following code listing shows how you can implement the StudentRepository class:

  public class StudentRepository : IRepository<Student>, IDisposable
  {
   
      private MyEntities _context;        
   
      public StudentRepository() 
      {            
          _context = new MyEntities();
      }
   
      public Student GetById(int id)
      {
          return _context.Students.
              Where(s => s.StudentID == id).
              FirstOrDefault();
      }
   
      public Student[] GetAll()
      {
          return _context.Students.ToArray();
      }
   
      public IQueryable<Student> Query(Expression<Func<Student, bool>> filter)
      {
          return _context.Students.Where(filter);
      }
  
      public void Save(Student student)
      {
         //Necessary code to persist a student record to the database
      }
  
      public void Delete(Student student)
      {
         //Necessary code to delete a student record
      }
   
      public void Dispose()
      {
          if (_context != null) 
          { 
              _context.Dispose(); 
          } 
       
         GC.SuppressFinalize(this);
      }
  }

Summary

The repository pattern provides a simple way to encapsulate the data access code in your application and promotes testable code, reusable code modules and separation of concerns between the data access logic and application's domain logic. In essence, the repository pattern promotes testability and usage of dependency injection, reduces the coupling or cohesion amongst the data access components and the application's domain model and abstracts the way data access code is written in your applications. In this article we discussed what the repository pattern is and how it can be implemented on top of LINQ and Entity Framework in your applications. Happy reading!

Suggested Readings

http://www.martinfowler.com/eaaCatalog/repository.html
http://weblogs.asp.net/fredriknormen/archive/2008/04/24/what-purpose-does-the-repository-pattern-have.aspx
http://www.codeproject.com/KB/architecture/linqrepository.aspx

Related Articles





About the Author

Joydip Kanjilal

Microsoft Most Valuable Professional, Author and Speaker. Featured in "MSDN Featured Developer of the Fortnight (India)" a number of times. Winner of Community Credit Awards at www.community-credit.com several times. Authored numerous books and articles in Microsoft .NET and its related technologies. Authored the following books:-- ASP.NET 4.0 Programming (Mc-Graw Hill Publishing) Entity Framework Tutorial (Packt Publishing) Pro Sync Framework (APRESS) Sams Teach Yourself ASP.NET Ajax in 24 Hours (Sams Publishing) ASP.NET Data Presentation Controls Essentials (Packt Publishing)

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: September 17, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Another day, another end-of-support deadline. You've heard enough about the hazards of not migrating to Windows Server 2008 or 2012. What you may not know is that there's plenty in it for you and your business, like increased automation and performance, time-saving technical features, and a lower total cost of ownership. Check out this upcoming eSeminar and join Rich Holmes, Pomeroy's practice director of virtualization, as he discusses the …

  • Live Event Date: September 16, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you starting an on-premise-to-cloud data migration project? Have you thought about how much space you might need for your online platform or how to handle data that might be related to users who no longer exist? If these questions or any other concerns have been plaguing you about your migration project, check out this eSeminar. Join our speakers Betsy Bilhorn, VP, Product Management at Scribe, Mike Virnig, PowerSucess Manager and Michele …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds