Here in this article I am going to explain Repository
Pattern in MVC application using Entity Framework.
First we need to know what Repository Pattern is. See
below Image.
MVC
Application without Repository Pattern:

Image 1.
MVC
Application with Repository pattern.

Image 2.
Repository Pattern separates the data access logic and
maps it to the entities in the business logic.
Now we will see Repository Pattern with a sample
application.
Open Visual Studio 2012 -> File New ->
Project->

Image 3.

Image 4.
Now Add a ADO.NET Entity Data Model in your
application. Right click on Project Solution Explorer -> Add ADO.NET Entity
Data Model.

Image 5.

Image 6.

Image 7.

Image 8.

Image 9.

Image 10.

Inage 11.
Now Add a New Folder in your Application name as DAL.
Right
Click on DAL Folder -> Add Interface -> IEmployeeRepository.cs

Image 12.
Now
my IEmployeeRepository.cs is:
using System;
using
System.Collections.Generic;
using System.Linq;
using System.Text;
using
System.Threading.Tasks;
namespace
RepositoryPatternInMVCWithEntityFramework.DAL
{
public interface IEmployeeRepository : IDisposable
{
IEnumerable<Employee>
GetAllEmployee();
Employee GetEmployeeByID(int emp_ID);
void InsertEmployee(Employee emp);
void DeleteEmployee(int emp_ID);
void UpdateEmployee(Employee emp);
void Save();
}
}
Now Again Right Click on DAL
Folder -> Add New Class -> EmployeeRepository.cs
and do below code:
using System;
using
System.Collections.Generic;
using System.Linq;
using System.Web;
using
RepositoryPatternInMVCWithEntityFramework.Models;
using System.Data;
namespace
RepositoryPatternInMVCWithEntityFramework.DAL
{
public class EmployeeRepository : IEmployeeRepository, IDisposable
{
private EmployeeManagementEntities context;
public EmployeeRepository(EmployeeManagementEntities context)
{
this.context = context;
}
public IEnumerable<Employee> GetAllEmployee()
{
return context.Employee.ToList();
}
public Employee GetEmployeeByID(int id)
{
return context.Employee.Find(id);
}
public void InsertEmployee(Employee emp)
{
context.Employee.Add(emp);
}
public void DeleteEmployee(int emp_ID)
{
Employee emp =
context.Employee.Find(emp_ID);
context.Employee.Remove(emp);
}
public void UpdateEmployee(Employee emp)
{
context.Entry(emp).State = EntityState.Modified;
}
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 Right Click on Controller Folder in your Project
Solution Explorer -> Add New Empty Controller -> EmployeeController &
do the below code:
EmployeeController
:
using
RepositoryPatternInMVCWithEntityFramework.DAL;
using System;
using
System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using
RepositoryPatternInMVCWithEntityFramework.Models;
using PagedList;
using System.Data;
namespace
RepositoryPatternInMVCWithEntityFramework.Controllers
{
public class EmployeeController : Controller
{
private IEmployeeRepository employeeRepository;
public EmployeeController()
{
this.employeeRepository = new EmployeeRepository(new EmployeeManagementEntities());
}
public EmployeeController(IEmployeeRepository employeeRepository)
{
this.employeeRepository = employeeRepository;
}
public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
ViewBag.CurrentSort = sortOrder;
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder)
? "Emp_ID"
: "";
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
ViewBag.CurrentFilter =
searchString;
var employees = from s in
employeeRepository.GetAllEmployee()
select s;
if (!String.IsNullOrEmpty(searchString))
{
employees = employees.Where(s
=> s.Name.ToUpper().Contains(searchString.ToUpper())
||
s.Name.ToUpper().Contains(searchString.ToUpper()));
}
switch (sortOrder)
{
case "Emp ID":
employees =
employees.OrderByDescending(s => s.Emp_ID);
break;
case "Name":
employees =
employees.OrderBy(s => s.Name);
break;
case "State":
employees =
employees.OrderByDescending(s => s.State);
break;
case "Country":
employees =
employees.OrderByDescending(s => s.Country);
break;
default:
employees =
employees.OrderBy(s => s.Emp_ID);
break;
}
int pageSize = 5;
int pageNumber = (page ?? 1);
return View(employees.ToPagedList(pageNumber,
pageSize));
}
//
// GET: /Employee/Details/5
public ViewResult Details(int id)
{
Employee emp =
employeeRepository.GetEmployeeByID(id);
return View(emp);
}
//
// GET: /Employee/Create
public ActionResult Create()
{
return View();
}
//
// POST: /Employee/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(
[Bind(Include = "Name, Email,
Designation,City, State, Country")]
Employee emp)
{
try
{
if
(ModelState.IsValid)
{
employeeRepository.InsertEmployee(emp);
employeeRepository.Save();
return RedirectToAction("Index");
}
}
catch (Exception ex)
{
ModelState.AddModelError(string.Empty, "Some Error
Occured.");
}
return View(emp);
}
//
// GET: /Employee/Edit/5
public ActionResult Edit(int id)
{
Employee emp =
employeeRepository.GetEmployeeByID(id);
return View(emp);
}
//
// POST: /Employee/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Employee emp)
{
try
{
if
(ModelState.IsValid)
{
employeeRepository.UpdateEmployee(emp);
employeeRepository.Save();
return RedirectToAction("Index");
}
}
catch (Exception ex)
{
ModelState.AddModelError(string.Empty, "Some error
Occured.");
}
return View(emp);
}
//
// GET: /employee/Delete/5
public ActionResult Delete(bool? saveChangesError =
false, int id = 0)
{
if (saveChangesError.GetValueOrDefault())
{
ViewBag.ErrorMessage = "Some Error
Occured.";
}
Employee emp =
employeeRepository.GetEmployeeByID(id);
return View(emp);
}
//
// POST: /Employee/Delete/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Delete(int id)
{
try
{
Employee emp =
employeeRepository.GetEmployeeByID(id);
employeeRepository.DeleteEmployee(id);
employeeRepository.Save();
}
catch (Exception ex)
{
return RedirectToAction("Delete", new { id = id,
saveChangesError = true });
}
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
employeeRepository.Dispose();
base.Dispose(disposing);
}
}
}
Now Add View. Right Click on
Index Action Method -> Add view :
(Index.cshtml)
@using PagedList.Mvc;
@model PagedList.IPagedList<RepositoryPatternInMVCWithEntityFramework.Employee>
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
@{
ViewBag.Title = "Employee
Management System";
}
<h2>Employee Management System</h2>
@using (Html.BeginForm("Index", "Employee", FormMethod.Get))
{
<p style="background-color:red; color:white; font-size:16pt; padding:10px;">
Search Employee By Name: @Html.TextBox("SearchString",
ViewBag.CurrentFilter as string)
<input type="submit" value="Search" />
@Html.ActionLink("Add New
Employee",
"Create")
</p>
}
<table style="background-color:white;">
<tr>
<th></th>
<th style="width: 100px;">
@Html.ActionLink("Emp ID", "Index", new { sortOrder =
ViewBag.NameSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
@Html.ActionLink("Name", "Index", new { sortOrder =
ViewBag.NameSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th>Email
</th>
<th>Designation
</th>
<th>City
</th>
<th>
@Html.ActionLink("State", "Index", new { sortOrder =
ViewBag.NameSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
@Html.ActionLink("Country", "Index", new { sortOrder =
ViewBag.NameSortParm, currentFilter = ViewBag.CurrentFilter })
</th>
<th style="width: 150px;"></th>
</tr>
@foreach (var item in Model)
{
<tr>
<td></td>
<td>
@Html.DisplayFor(modelItem
=> item.Emp_ID)
</td>
<td style="width:130px;">
@Html.DisplayFor(modelItem
=> item.Name)
</td>
<td>
@Html.DisplayFor(modelItem
=> item.Email)
</td>
<td style="width:140px;">
@Html.DisplayFor(modelItem
=> item.Designation)
</td>
<td style="width:120px;">
@Html.DisplayFor(modelItem
=> item.City)
</td>
<td style="width:120px;">
@Html.DisplayFor(modelItem
=> item.State)
</td>
<td>
@Html.DisplayFor(modelItem
=> item.Country)
</td>
<td style="width:270px;">
@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>
<br />
<div style="background-color:orange; padding-left:15px; padding-top:10px;">
Showing Records @(Model.PageCount <
Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount
@Html.PagedListPager(Model, page =>
Url.Action("Index",
new { page, sortOrder =
ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
</div>
Here
I am using PagedList. You can add the reference of PagedList by right clicking on
Solution Explorer -> Manage NuGet Packages

Image 13.

Image 14.
Now Add Detail View by Right
Clicking on Details Action Method
Details.cshtml (Make it Strongly
Typed View with class Employee
& Scaffold template Details)
@model RepositoryPatternInMVCWithEntityFramework.Employee
<h2>Employee Details</h2>
<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="background-color: orange; padding: 25px;">
<td></td>
<td>@Html.ActionLink("Edit", "Edit", new { id = Model.Emp_ID
}) |
@Html.ActionLink("Back to
List",
"Index")</td>
</tr>
</table>
Now
Add Create View by Right Clicking on Create Action Method
Create.cshtml
@model RepositoryPatternInMVCWithEntityFramework.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.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>
Now
Add Edit View by Right Clicking on Edit Action Method
Edit.cshtml
@model RepositoryPatternInMVCWithEntityFramework.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>
<h2>Edit Employee information</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<table>
<tr>
<td>@Html.LabelFor(model => model.Emp_ID)</td>
<td>
@Html.EditorFor(model
=> model.Emp_ID, new { disabled = "disabled", @readonly = "readonly" })
@Html.ValidationMessageFor(model
=> model.Emp_ID)</td>
</tr>
<tr>
<td>@Html.LabelFor(model => model.Name)
</td>
<td>@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model
=> model.Name)</td>
</tr>
<tr>
<td>@Html.LabelFor(model => model.Email)</td>
<td>
@Html.EditorFor(model
=> model.Email)
@Html.ValidationMessageFor(model
=> model.Email)</td>
</tr>
<tr>
<td>@Html.LabelFor(model =>
model.Designation)</td>
<td>
@Html.EditorFor(model
=> model.Designation)
@Html.ValidationMessageFor(model
=> model.Designation)
</td>
</tr>
<tr>
<td>@Html.LabelFor(model => model.City)</td>
<td>
@Html.EditorFor(model
=> model.City)
@Html.ValidationMessageFor(model =>
model.City)</td>
</tr>
<tr>
<td>@Html.LabelFor(model => model.State)</td>
<td>@Html.EditorFor(model => model.State)
@Html.ValidationMessageFor(model
=> model.State)</td>
</tr>
<tr>
<td>@Html.LabelFor(model => model.Country)</td>
<td>
@Html.EditorFor(model
=> model.Country)
@Html.ValidationMessageFor(model
=> model.Country)</td>
</tr>
<tr style="background-color: orange; padding: 25px;">
<td></td>
<td>
<input type="submit" value="Save" />
@Html.ActionLink("Back to
List",
"Index")
</td>
</tr>
</table>
}
Now
Add Delete View by Right Clicking on Delete Action Method
Delete.cshtml
@model RepositoryPatternInMVCWithEntityFramework.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()
<table>
<tr style="background-color: orange; padding: 25px;">
<td></td>
<td>
<input type="submit" value="Delete" />
@Html.ActionLink("Back to
List",
"Index")
</td>
</tr>
</table>
}
Now
Run Application #
Showing All Records with
Paging & Sorting.

Image 15.
Now go on page 3 .

Image 16.
Now do search.

Image 17.
Now Click on Add New Employer

Image 18.
Now click on any records Edit
button.

Image 19.
Now click on Detail .

Image 20.
Now click on Delete option.

Image 21.
To perform CRUD operation you
will notice we are not calling DB method directly here. We are using repository
pattern.
For this application My
Employee Table is design mode is:

Image 22.
Script of My Table is:
CREATE TABLE [dbo].[Employee](
[Emp_ID] [int]
IDENTITY(1,1) NOT NULL,
[Name]
[varchar](50) NULL,
[Email]
[varchar](500) NULL,
[Designation]
[varchar](50) NULL,
[City]
[varchar](50) NULL,
[State]
[varchar](50) NULL,
[Country]
[varchar](50) NULL,
CONSTRAINT [PK_Employee] PRIMARY
KEY CLUSTERED
(
[Emp_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS
= ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
Data in My Table is:

Image 23.
Enjoy Programming J
Next I will write about
Generic Repository Pattern.