Introduction
Our roadmap towards Learning MVC
-
- 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.
Pre-requisites
- We have running sample application that we created in fifth part of the article series.
- We have Entity Framework 4.1 package or DLL on our local file system.
- We understand how MVC application is created (follow second part of the series).
Why Generic Repository


Unit of Work Pattern
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.- To manage transactions.
- To order the database inserts, deletes, and updates.
- To prevent duplicate updates. Inside a single usage of a Unit of Work object, different 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.
Why use Unit of Work?

Using the Unit of Work
Creating a Generic Repository

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 where TEntity : class
{
internal MVCEntities context;
internal DbSet dbSet;
public GenericRepository(MVCEntities context)
{
this.context = context;
this.dbSet = context.Set();
}
public virtual IEnumerable Get()
{
IQueryable 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;
}
}
}
TEntity
is any model/domain/entity class. MVCEntities
is our DBContext
as discussed in earlier parts.using System; using LearningMVC.GenericRepository;
namespace LearningMVC.UnitOfWork
{
public class UnitOfWork : IDisposable
{
private MVCEntities context = new MVCEntities();
private GenericRepository userRepository;
public GenericRepository UserRepository
{
get
{
if (this.userRepository == null)
this.userRepository = new GenericRepository(context);
return userRepository;
}
}
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);
}
}
}
IDisposable
interface for objects of this class to be disposed.DBContext
in this class, note that earlier it was used to be passed in Repository class from a controller.userRepository
is declared as private GenericRepository userRepository;
of type GenericRepository
serving User entity to TEntity
template.userRepository
variable in a very simplified manner,public GenericRepository UserRepository { get { if (this.userRepository == null) this.userRepository = new GenericRepository(context); return userRepository; } }

DBOperations
, let’s do it.MyController
, declare a variable unitOfWork
as:private UnitOfWork.UnitOfWork unitOfWork = new UnitOfWork.UnitOfWork();
public ActionResult Index() { var userList = from user in unitOfWork.UserRepository.Get() select user; var users = new List(); if (userList.Any()) { foreach (var user in userList) { users.Add(new LearningMVC.Models.UserList() { UserId = user.UserId, Address = user.Address, Company = user.Company, FirstName = user.FirstName, LastName = user.LastName, Designation = user.Designation, EMail = user.EMail, PhoneNo = user.PhoneNo }); } } ViewBag.FirstName = "My First Name"; ViewData["FirstName"] = "My First Name"; if(TempData.Any()) { var tempData = TempData["TempData Name"]; } return View(users); }
unitOfWork.UserRepository
> AccessingUserRepository
.unitOfWork.UserRepository.Get()
-> Accessing GenericGet()
method to get all users.
MyController
constructor like:public MyController() { this.userRepository = new UserRepository(new MVCEntities()); }
UserRepository
class and Interface we created in part 5 of Learning MVC.Details
public ActionResult Details(int id) { var userDetails = unitOfWork.UserRepository.GetByID(id); var user = new LearningMVC.Models.UserList(); if (userDetails != null) { user.UserId = userDetails.UserId; user.FirstName = userDetails.FirstName; user.LastName = userDetails.LastName; user.Address = userDetails.Address; user.PhoneNo = userDetails.PhoneNo; user.EMail = userDetails.EMail; user.Company = userDetails.Company; user.Designation = userDetails.Designation; } return View(user); }
[HttpPost] public ActionResult Create(LearningMVC.Models.UserList userDetails) { try { var user = new User(); if (userDetails != null) { user.UserId = userDetails.UserId; user.FirstName = userDetails.FirstName; user.LastName = userDetails.LastName; user.Address = userDetails.Address; user.PhoneNo = userDetails.PhoneNo; user.EMail = userDetails.EMail; user.Company = userDetails.Company; user.Designation = userDetails.Designation; } unitOfWork.UserRepository.Insert(user); unitOfWork.Save(); return RedirectToAction("Index"); } catch { return View(); } }
public ActionResult Edit(int id) { var userDetails = unitOfWork.UserRepository.GetByID(id); var user = new LearningMVC.Models.UserList(); if (userDetails != null) { user.UserId = userDetails.UserId; user.FirstName = userDetails.FirstName; user.LastName = userDetails.LastName; user.Address = userDetails.Address; user.PhoneNo = userDetails.PhoneNo; user.EMail = userDetails.EMail; user.Company = userDetails.Company; user.Designation = userDetails.Designation; } return View(user); }
[HttpPost]
public ActionResult Edit(int id, User userDetails)
{
TempData[“TempData Name”] = “Akhil”;
try
{
var user = unitOfWork.UserRepository.GetByID(id);
user.FirstName = userDetails.FirstName;
user.LastName = userDetails.LastName;
user.Address = userDetails.Address;
user.PhoneNo = userDetails.PhoneNo;
user.EMail = userDetails.EMail;
user.Company = userDetails.Company;
user.Designation = userDetails.Designation;
unitOfWork.UserRepository.Update(user);
unitOfWork.Save();
return RedirectToAction(“Index”);
}
public ActionResult Delete(int id) { var user = new LearningMVC.Models.UserList(); var userDetails = unitOfWork.UserRepository.GetByID(id);
if (userDetails != null)
{
user.FirstName = userDetails.FirstName;
user.LastName = userDetails.LastName;
user.Address = userDetails.Address;
user.PhoneNo = userDetails.PhoneNo;
user.EMail = userDetails.EMail;
user.Company = userDetails.Company;
user.Designation = userDetails.Designation;
}
return View(user);
}
[HttpPost]
public ActionResult Delete(int id, LearningMVC.Models.UserList userDetails)
{
try
{
var user = unitOfWork.UserRepository.GetByID(id);
if (user != null)
{
unitOfWork.UserRepository.Delete(id);
unitOfWork.Save();
}
return RedirectToAction(“Index”);
}
catch
{
return View();
}
}
Conclusion
We have also learnt UnitOfWork pattern in detail. Now you are qualified and confident enough to apply these concepts in your enterprise applications. This was the last part of this MVC series, let me know if you feel to discuss any topic in particular or we can also start any other series as well.
Read more:
- C# and ASP.NET Questions (All in one)
- MVC Interview Questions
- C# and ASP.NET Interview Questions and Answers
- Web Services and Windows Services Interview Questions
Other Series
My other series of articles:
For more informative articles visit my Blog.
For more technical articles you can reach out to CodeTeddy.
Where do you dispose your Repository?
LikeLike
Thanks
LikeLike
Fantastic article!
Well done.
LikeLike