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

Image 1.

Image 2.
Now Create a DAL folder in your application -> Right Click DAL Folder -> Add New ADO.NET Entity Data model.

Image 3.

Image 4.

Image 5.

Image 6.

Image 7.

Image 8.

Image 9.
Now suppose there are more than one entity in your data base then you
have to create I-Repository & Repository for each and every entity and need
to do same code. To avoid this we will define a generic repository like below:
Right Click on DAL Folder -> 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;
}
}
}
Now we will
define a Unit Of Work: Right Click on DAL Folder -> Add New Class
Here we will
define all our Repository likes below:
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 name as Employee:

Image 10.

Image 11.
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);
}
}
}
Now My Views are:
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>
Details.cshtml
@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>
Create.cshtml
@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>
Edit.cshtml
@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>
Delete.cshtml
@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 your application

Image 12.
Add New Employee.

Image 13.
Click on Details.

Image 14.
Click on Edit

Image 15.
Click on Delete.

Image 16.
Here you can see in controller we are calling UnitOfWork and have mapped
our repository with generic Repository. So no need to write code again and
again.
Enjoy Generic Repository. J