In my previous article I explained the Repository Pattern in MVC. Now I will explain the Generic Repository.
Repository Pattern In MVC Application Using Entity Framework
So the question is, when we have a Repository Pattern, then what is this Generic Pattern? What do we need the Generic Pattern for? The following is the answer.
It may be that our database has many tables so we need to create a repository class for each entity type. That simply means that there are many chances for repeating the code. It can be a problematic thing. Suppose we need to update two different entity types as part of the same transactions.
If every entity use a separate database context instance, one might succeed and another can fail. So to avoid this type of situation we have a Generic Repository. It is a way to ensure that all repositories use the same database context (and thus coordinates all the updates) using a unit of work class.
Unit of work is a pattern to handle transactions during data manipulation using the Repository Pattern.
Now we will learn about this by creating a MVC application as in the following:
Open Visual Studio 2010 then go to File -> New -> Project.

Now create a DAL folder in your application then right-click the DAL Folder then select Add -> ADO.NET Entity Data model.






Now suppose there is more than one entity in your database. Then you need to create an I-Repository and Repository for each and every entity and need to do the same code. To avoid this we will define a generic repository as in the following.
Right-click on the DAL Folder then select Add New Class-> GenericRepositiory.cs.
GenericRepositiory.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using GenericRepositioryPatternInMVC4.Models;
- using System.Linq.Expressions;
- using System.Data;
- using System.Data.Entity;
- namespace GenericRepositioryPatternInMVC4.DAL
- {
- public class GenericRepository<TEntity> where TEntity : class
- {
- internal EmployeeManagementEntities context;
- internal DbSet<TEntity> dbSet;
- public GenericRepository(EmployeeManagementEntities context)
- {
- this.context = context;
- this.dbSet = context.Set<TEntity>();
- }
- public virtual IEnumerable<TEntity> Get(
- Expression<Func<TEntity, bool>> filter = null,
- Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
- string includeProperties = "")
- {
- IQueryable<TEntity> query = dbSet;
- if (filter != null)
- {
- query = query.Where(filter);
- }
- foreach (var includeProperty in includeProperties.Split
- (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
- {
- query = query.Include(includeProperty);
- }
- if (orderBy != null)
- {
- return orderBy(query).ToList();
- }
- else
- {
- 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;
- }
- }
- }
Here we will define all our Repositories like the following.
UnitOfWork.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- namespace GenericRepositioryPatternInMVC4.DAL
- {
- public class UnitOfWork : IDisposable
- {
- private EmployeeManagementEntities context = new EmployeeManagementEntities();
- private GenericRepository<Employee> employeeRepository;
- public GenericRepository<Employee> EmployeeRepository
- {
- get
- {
- if (this.employeeRepository == null)
- {
- this.employeeRepository = new GenericRepository<Employee>(context);
- }
- return employeeRepository;
- }
- }
- public void Save()
- {
- context.SaveChanges();
- }
- private bool disposed = false;
- protected virtual void Dispose(bool disposing)
- {
- if (!this.disposed)
- {
- if (disposing)
- {
- context.Dispose();
- }
- }
- this.disposed = true;
- }
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- }
- }
Now add a Controller named Employee:


Now EmployeeController is:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.Mvc;
- using GenericRepositioryPatternInMVC4.Models;
- using GenericRepositioryPatternInMVC4.DAL;
- using System.Data;
- namespace GenericRepositioryPatternInMVC4.Controllers
- {
- public class EmployeeController : Controller
- {
- private UnitOfWork unitOfWork = new UnitOfWork();
- //
- // GET: /Employee/
- public ViewResult Index()
- {
- var employee = unitOfWork.EmployeeRepository.Get();
- return View(employee.ToList());
- }
- //
- // GET: /employee/Details/5
- public ViewResult Details(int id)
- {
- Employee employee = unitOfWork.EmployeeRepository.GetByID(id);
- return View(employee);
- }
- //
- // GET: /employee/Create
- public ActionResult Create()
- {
- return View();
- }
- [HttpPost]
- [ValidateAntiForgeryToken]
- public ActionResult Create(Employee employee)
- {
- try
- {
- if (ModelState.IsValid)
- {
- unitOfWork.EmployeeRepository.Insert(employee);
- unitOfWork.Save();
- return RedirectToAction("Index");
- }
- }
- catch (Exception ex)
- {
- ModelState.AddModelError("", "Some Error Occurred.");
- }
- return View(employee);
- }
- public ActionResult Edit(int id)
- {
- Employee employee = unitOfWork.EmployeeRepository.GetByID(id);
- return View(employee);
- }
- [HttpPost]
- [ValidateAntiForgeryToken]
- public ActionResult Edit(Employee employee)
- {
- try
- {
- if (ModelState.IsValid)
- {
- unitOfWork.EmployeeRepository.Update(employee);
- unitOfWork.Save();
- return RedirectToAction("Index");
- }
- }
- catch (Exception ex)
- {
- ModelState.AddModelError("", "Some Error Occurred");
- }
- return View(employee);
- }
- //
- // GET: /employee/Delete/5
- public ActionResult Delete(int id)
- {
- Employee employee = unitOfWork.EmployeeRepository.GetByID(id);
- return View(employee);
- }
- //
- // POST: /employee/Delete/5
- [HttpPost, ActionName("Delete")]
- [ValidateAntiForgeryToken]
- public ActionResult DeleteConfirmed(int id)
- {
- Employee employee = unitOfWork.EmployeeRepository.GetByID(id);
- unitOfWork.EmployeeRepository.Delete(id);
- unitOfWork.Save();
- return RedirectToAction("Index");
- }
- protected override void Dispose(bool disposing)
- {
- unitOfWork.Dispose();
- base.Dispose(disposing);
- }
- }
- }
Index.cshtml
- @model IEnumerable<GenericRepositioryPatternInMVC4.DAL.Employee>
- @{
- ViewBag.Title = "Generic Repository Pattern In MVC4";
- }
- <p>
- @Html.ActionLink("Add New Employee", "Create")
- </p>
- <table>
- <tr>
- <th>
- @Html.DisplayNameFor(model => model.Emp_ID)
- </th>
- <th>
- @Html.DisplayNameFor(model => model.Name)
- </th>
- <th>
- @Html.DisplayNameFor(model => model.Email)
- </th>
- <th>
- @Html.DisplayNameFor(model => model.Designation)
- </th>
- <th>
- @Html.DisplayNameFor(model => model.City)
- </th>
- <th>
- @Html.DisplayNameFor(model => model.State)
- </th>
- <th>
- @Html.DisplayNameFor(model => model.Country)
- </th>
- <th></th>
- </tr>
- @foreach (var item in Model)
- {
- <tr>
- <td>
- @Html.DisplayFor(modelItem => item.Emp_ID)
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.Name)
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.Email)
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.Designation)
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.City)
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.State)
- </td>
- <td>
- @Html.DisplayFor(modelItem => item.Country)
- </td>
- <td>
- @Html.ActionLink("Edit", "Edit", new { id=item.Emp_ID }) |
- @Html.ActionLink("Details", "Details", new { id=item.Emp_ID }) |
- @Html.ActionLink("Delete", "Delete", new { id=item.Emp_ID })
- </td>
- </tr>
- }
- </table>
- @model GenericRepositioryPatternInMVC4.DAL.Employee
- <table>
- <tr>
- <td>@Html.DisplayNameFor(model => model.Emp_ID)</td>
- <td>@Html.DisplayFor(model => model.Emp_ID)</td>
- </tr>
- <tr>
- <td>@Html.DisplayNameFor(model => model.Name)</td>
- <td>@Html.DisplayFor(model => model.Name)</td>
- </tr>
- <tr>
- <td>@Html.DisplayNameFor(model => model.Email)</td>
- <td>@Html.DisplayFor(model => model.Email)</td>
- </tr>
- <tr>
- <td>@Html.DisplayNameFor(model => model.Designation)</td>
- <td>@Html.DisplayFor(model => model.Designation)</td>
- </tr>
- <tr>
- <td>@Html.DisplayNameFor(model => model.City)</td>
- <td>@Html.DisplayFor(model => model.City)</td>
- </tr>
- <tr>
- <td>@Html.DisplayNameFor(model => model.State)</td>
- <td>@Html.DisplayFor(model => model.State)</td>
- </tr>
- <tr>
- <td>@Html.DisplayNameFor(model => model.Country)</td>
- <td>@Html.DisplayFor(model => model.Country)</td>
- </tr>
- <tr style="padding: 25px;">
- <td></td>
- <td>@Html.ActionLink("Edit", "Edit", new { id = Model.Emp_ID }) |
- @Html.ActionLink("Back to List", "Index")</td>
- </tr>
- </table>
- @model GenericRepositioryPatternInMVC4.DAL.Employee
- <script src="~/Scripts/jquery-1.7.1.min.js"></script>
- <script src="~/Scripts/jquery.validate.min.js"></script>
- <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
- @using (Html.BeginForm())
- {
- @Html.AntiForgeryToken()
- @Html.ValidationSummary(true)
- <fieldset>
- <legend>Employee</legend>
- <div class="editor-label">
- @Html.LabelFor(model => model.Emp_ID)
- </div>
- <div class="editor-field">
- @Html.EditorFor(model => model.Emp_ID)
- @Html.ValidationMessageFor(model => model.Emp_ID)
- </div>
- <div class="editor-label">
- @Html.LabelFor(model => model.Name)
- </div>
- <div class="editor-field">
- @Html.EditorFor(model => model.Name)
- @Html.ValidationMessageFor(model => model.Name)
- </div>
- <div class="editor-label">
- @Html.LabelFor(model => model.Email)
- </div>
- <div class="editor-field">
- @Html.EditorFor(model => model.Email)
- @Html.ValidationMessageFor(model => model.Email)
- </div>
- <div class="editor-label">
- @Html.LabelFor(model => model.Designation)
- </div>
- <div class="editor-field">
- @Html.EditorFor(model => model.Designation)
- @Html.ValidationMessageFor(model => model.Designation)
- </div>
- <div class="editor-label">
- @Html.LabelFor(model => model.City)
- </div>
- <div class="editor-field">
- @Html.EditorFor(model => model.City)
- @Html.ValidationMessageFor(model => model.City)
- </div>
- <div class="editor-label">
- @Html.LabelFor(model => model.State)
- </div>
- <div class="editor-field">
- @Html.EditorFor(model => model.State)
- @Html.ValidationMessageFor(model => model.State)
- </div>
- <div class="editor-label">
- @Html.LabelFor(model => model.Country)
- </div>
- <div class="editor-field">
- @Html.EditorFor(model => model.Country)
- @Html.ValidationMessageFor(model => model.Country)
- </div>
- <p>
- <input type="submit" value="Create" />
- </p>
- </fieldset>
- }
- <div>
- @Html.ActionLink("Back to List", "Index")
- </div>
- @model GenericRepositioryPatternInMVC4.DAL.Employee
- <script src="~/Scripts/jquery-1.7.1.min.js"></script>
- <script src="~/Scripts/jquery.validate.min.js"></script>
- <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
- @using (Html.BeginForm())
- {
- @Html.AntiForgeryToken()
- @Html.ValidationSummary(true)
- <fieldset>
- <legend>Employee</legend>
- <div class="editor-label">
- @Html.LabelFor(model => model.Emp_ID)
- </div>
- <div class="editor-field">
- @Html.EditorFor(model => model.Emp_ID)
- @Html.ValidationMessageFor(model => model.Emp_ID)
- </div>
- <div class="editor-label">
- @Html.LabelFor(model => model.Name)
- </div>
- <div class="editor-field">
- @Html.EditorFor(model => model.Name)
- @Html.ValidationMessageFor(model => model.Name)
- </div>
- <div class="editor-label">
- @Html.LabelFor(model => model.Email)
- </div>
- <div class="editor-field">
- @Html.EditorFor(model => model.Email)
- @Html.ValidationMessageFor(model => model.Email)
- </div>
- <div class="editor-label">
- @Html.LabelFor(model => model.Designation)
- </div>
- <div class="editor-field">
- @Html.EditorFor(model => model.Designation)
- @Html.ValidationMessageFor(model => model.Designation)
- </div>
- <div class="editor-label">
- @Html.LabelFor(model => model.City)
- </div>
- <div class="editor-field">
- @Html.EditorFor(model => model.City)
- @Html.ValidationMessageFor(model => model.City)
- </div>
- <div class="editor-label">
- @Html.LabelFor(model => model.State)
- </div>
- <div class="editor-field">
- @Html.EditorFor(model => model.State)
- @Html.ValidationMessageFor(model => model.State)
- </div>
- <div class="editor-label">
- @Html.LabelFor(model => model.Country)
- </div>
- <div class="editor-field">
- @Html.EditorFor(model => model.Country)
- @Html.ValidationMessageFor(model => model.Country)
- </div>
- <p>
- <input type="submit" value="Save" />
- </p>
- </fieldset>
- }
- <div>
- @Html.ActionLink("Back to List", "Index")
- </div>
- @model GenericRepositioryPatternInMVC4.DAL.Employee
- <h3>Are you sure you want to delete this?</h3>
- <table>
- <tr>
- <td>@Html.DisplayNameFor(model => model.Emp_ID)</td>
- <td>@Html.DisplayFor(model => model.Emp_ID)</td>
- </tr>
- <tr>
- <td>@Html.DisplayNameFor(model => model.Name)</td>
- <td>@Html.DisplayFor(model => model.Name)</td>
- </tr>
- <tr>
- <td>@Html.DisplayNameFor(model => model.Email)</td>
- <td>@Html.DisplayFor(model => model.Email)</td>
- </tr>
- <tr>
- <td>@Html.DisplayNameFor(model => model.Designation)</td>
- <td>@Html.DisplayFor(model => model.Designation)</td>
- </tr>
- <tr>
- <td>@Html.DisplayNameFor(model => model.City)</td>
- <td>@Html.DisplayFor(model => model.City)</td>
- </tr>
- <tr>
- <td>@Html.DisplayNameFor(model => model.State)</td>
- <td>@Html.DisplayFor(model => model.State)</td>
- </tr>
- <tr>
- <td>@Html.DisplayNameFor(model => model.Country)</td>
- <td>@Html.DisplayFor(model => model.Country)</td>
- </tr>
- </table>
- @using (Html.BeginForm())
- {
- @Html.AntiForgeryToken()
- <p>
- <input type="submit" value="Delete" /> |
- @Html.ActionLink("Back to List", "Index")
- </p>
- }
Now run the application.

Add a new Employee.
Click on Details.
Click on Edit.
Click on Delete.
Here you can see in the controller we are calling UnitOfWork and have mapped our repository with a Generic Repository. So there is no need to write code again and again.
Enjoy Generic Repositories.

rajendra singhPosted May 21, 2018, 11:35 PM
Good one, could you please tell does we needs to create separate unit of work classes for performing crud operations.
Rahul Kumar SaxenaPosted Apr 6, 2015, 5:20 AM
Thanks Mahesh Alle
Mahesh AllePosted Apr 6, 2015, 12:58 AM
Nice one. Thanks