Introduction
Creating a Generic Repository Pattern in MVC3 Application with Entity Framework is the last topic that we are about to cover in our journey of Learning MVC.
This article will focus on the Unit Of Work Pattern and Repository Pattern, and shows how to perform CRUD operations in an MVC application when there is the possibility of creating more than one repository class. To overcome this possibility and overhead, we make a Generic Repository class for all other repositories and implement a Unit of Work pattern to provide abstraction.
Our roadmap towards Learning MVC
Just as a reminder, our full roadmap towards learning MVC is:
- Part1: Introduction to MVCarchitecture and Separation of Concerns.VCarchitecture and Separation of Concerns.
- Part 2: Creating MVC Application fromscratch and connecting it with database using LINQ to SQL.
- Part 3: Connecting the MVC Application with the help of EntityFramework DB-First approach.
- Part 4: Connecting the MVC Application with the help of EntityFramework Code-First approach.
- Part 5: Implementing Repository Pattern in MVC Application with EntityFramework.
- Part 6: Implementing a generic Repository Pattern and Unit Of Work pattern in MVC Application with EntityFramework.
Prerequisites
There are a few prerequisites before we starting with the article; they are:
- We have a running sample application that we created in the fifth part of the article series.
- We have the EntityFramework 4.1 package or DLL in our local system.
- We understand how a MVC application is created (follow the second part of the series).
Why Generic Repository
We have already discussed what the Repository Pattern is and why we need the Repository Pattern in our last article. We created a User Repository for performing CRUD operations, but think of the scenario where we need 10 such repositories.
Are we going to create these classes? That is not good, it results in a lot of redundant code. So to overcome that we'll create a Generic Repository class that will be called by a property to create a new repository, thus we do not get many results in many classes and also avoid redundant code. Moreover we save a lot of time that could be wasted creating those classes.
Unit of Work Pattern
According to Martin Fowler, the Unit of Work Pattern "Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems.".
From MSDN:
"The Unit of Work pattern isn't necessarily something that you will explicitly build yourself, but the pattern shows up in nearly every persistence tool. The ITransaction interface in NHibernate, the DataContext class in LINQ to SQL, and the ObjectContext class in the Entity Framework are all examples of a Unit of Work. For that matter, the venerable DataSet can be used as a Unit of Work.
Other times, you may want to write your own application-specific Unit of Work interface or class that wraps the inner Unit of Work from your persistence tool. You may do this for a number of reasons. You might want to add application-specific logging, tracing, or error handling to transaction management. Perhaps you want to encapsulate the specifics of your persistence tooling from the rest of the application. You might want this extra encapsulation to make it easier to swap out persistence technologies later. Or you might want to promote testability in your system. Many of the built-in Unit of Work implementations from common persistence tools are difficult to deal with in automated unit testing scenarios.
The Unit of Work class can have methods to mark entities as modified, newly created, or deleted. The Unit of Work will also have methods to commit or roll back all of the changes as well.
The responsibilities of the Unit of Work are to:
- Manage transactions.
- Order the database inserts, deletes, and updates.
- Prevent duplicate updates. Inside a single usage of a Unit of Work object, various parts of the code may mark the same Invoice object as changed, but the Unit of Work class will only issue a single UPDATE command to the database.
The value of using a Unit of Work pattern is to free the rest of our code from these concerns so that you can otherwise concentrate on business logic."
Why use Unit of Work?
Again Martin Fowler says,"When you're pulling data in and out of a database, it's important to keep track of what you've changed; otherwise, that data won't be written back into the database. Similarly you need to insert new objects you create and remove any objects you delete.
You can change the database with each change to your object model, but this can lead to many very small database calls, which ends up being very slow. Furthermore it requires you to have a transaction open for the entire interaction, which is impractical if you have a business transaction that spans multiple requests. The situation is even worse if you need to keep track of the objects you've read so you can avoid inconsistent reads.
A Unit of Work keeps track and takes responsibility of everything you do during a business transaction that can affect the database. When you're done, it figures out everything that needs to be done to alter the database as a result of your work."
You see I don't need to concentrate much on theory, we already have great definitions, all we needed is to stack them in a correct format.
Using the Unit of Work
One of the best ways to use the Unit of Work pattern is to allow disparate classes and services to take part in a single logical transaction. The key point here is that you want the disparate classes and services to remain ignorant of each other while being able to enlist in a single transaction. Traditionally, you've been able to do this by using transaction coordinators like MTS/COM+ or the newer System.Transactions namespace. Personally, I prefer using the Unit of Work pattern to allow unrelated classes and services to take part in a logical transaction because I think it makes the code more explicit, easier to understand, and simpler to unit test (also from MSDN).
Creating Generic Repository
Cut the Redundancy
Step 1 : Open up our existing MVC3 application created in Part 5 in Visual Studio.
Step 2 : Right-click the Learning MVC project folder and create a folder named GenericRepository and add a class named GenericRepository.cs to that folder.
The code of the GenericRepository.cs class is as follows:
- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.Data.Entity;
- using System.Linq;
- using System.Linq.Expressions;
- namespace LearningMVC.GenericRepository
- {
- public class GenericRepository<TEntity> where TEntity : class
- {
- internal MVCEntities context;
- internal DbSet<TEntity> dbSet;
- public GenericRepository(MVCEntities context)
- {
- this.context = context;
- this.dbSet = context.Set<TEntity>();
- }
- public virtual IEnumerable<TEntity> Get()
- {
- IQueryable<TEntity> query = dbSet;
- return query.ToList();
- }
- public virtual TEntity GetByID(object id)
- {
- return dbSet.Find(id);
- }
- public virtual void Insert(TEntity entity)
- {
- dbSet.Add(entity);
- }
- public virtual void Delete(object id)
- {
- TEntity entityToDelete = dbSet.Find(id);
- Delete(entityToDelete);
- }
- public virtual void Delete(TEntity entityToDelete)
- {
- if (context.Entry(entityToDelete).State == EntityState.Detached)
- {
- dbSet.Attach(entityToDelete);
- }
- dbSet.Remove(entityToDelete);
- }
- public virtual void Update(TEntity entityToUpdate)
- {
- dbSet.Attach(entityToUpdate);
- context.Entry(entityToUpdate).State = EntityState.Modified;
- }
- }
- }
We can see, we have created the generic methods and the class as well is generic, when instantiating this class we can any model on which the class will work as a repository and serve the purpose.
TEntity is any model/domain/entity class.
MVCEntities is our DBContext as discussed in earlier parts.
Step 3 : Implementing UnitOfWork: Create a folder named UnitOfWork under the LearningMVC project, and add a class UnitOfWork.cs to that folder.
The code of the class is as follows:

Debasis SahaPosted Apr 15, 2016, 12:32 AM
Nice article..
Kuppurasu NagarajPosted Apr 14, 2016, 9:18 AM
Nice Sharing..
Rahul Kumar SaxenaPosted Apr 14, 2016, 6:23 AM
Good Show
Gowtham RajamanickamPosted Apr 14, 2016, 6:06 AM
nice article..
Akhil MittalPosted Sep 20, 2013, 12:33 AM
I disagree.The provided code is an architecture,you can always extend it.and for your SQL query,there are where clause predicates in LINQ.You can create a generic method in Generic Repository class which contains a where clause predicate as a parameter.Try it.
Ionut CorneanuPosted Sep 19, 2013, 10:24 AM
This solution looks nice in theory but it is impractical in practice. You shouldn't get all the entities in memory and then filter them. Also, what if you have a complex query, say you want to get all users that have their Firstname = "John"? What will you do? Get all users in memory and then filter them? What if you have 50 thousands users? You will get them all?
ad codersPosted Aug 21, 2013, 4:23 AM
Detailed Presentation. Good One.