Introduction
Repository pattern is used to create an abstraction layer between the data access layer and
the business logic layer. This abstraction layer contains data manipulation methods which
communicate with the data access layer to serve data as per the business requirements to
the logical layer. The main purpose to create this layer is for isolating data access layer so that changes cannot affect
the business logic layer directly.
For example, a POS application is usually deployed to different stores. A few new clients wanted to use
the Microsoft SQL Server database system and some others wanted Oracle and other databases. Also they had
a few different relational database systems to store their data but business logic
was almost the same. Repository pattern helps developers to detach the layer and add
a new data access layer.
Unit of work is a pattern to handle transaction during data manipulation using
the Repository pattern. So we can say, according to Martin Fowler, Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problem.
Implementing these patterns can help insulate the application from changes in the data store and also gives advantages to automate unit testing. Though these patterns are widely used for DDD,
they facilitate for TDD also.

What is ORM and EF
Object-relational mapping is a programming technique for converting data between incompatible type systems in relational databases and object-oriented programming languages.
We can handle objects/models as a schema of the database object. We can write code/query on model object collections which
load data by maintaining database relations.
Advantages of ORM
- Data manipulation (CRUD) is handled without writing SQL queries
- Data mapping between result set and entity collection/entity is one of the major features of ORM
- Using UoW/Context, it can handle the transaction during data manipulation
- Writing one Data Model in a single place for managing the model’s storage in DB.
- It fits the natural way of coding with application’s language.
- Programmers can think fully object oriented way to make any operation with business logic layer and data storage.
So nowadays, nobody should think of using DAO or a traditional approach to access
a database if there is no special purpose; using ORM not only reduces writing code
but also helps us to think only with business objects or data objects.
Entity framework is a popular object relational mapper that enables .NET developers to work with relational data using domain-specific objects. This framework supports to write POCO and generate database and is also able to create model from existing database. To know more details of the Entity framework, please visit this link.
Design your Independent/Generic repository functionality.
Now you can write different repository class for each entity. But for database operation, few common methods will be used for CRUD operation and others. So using different repository creates redundant code to the application. That’s why you should create the generic repository.
To design an independent or generic repository, follow the below steps:
In the first step, you have to create an ASP.NET MVC web application to store personal contacts. Please open a new project to choose the template ASP.NET MVC 4 Web Application.

Then add another project to solution for data access named Contact.Repository.

Create a database for the application with the following tables:

Now jump to the code and add an ADO.NET Entity Data Model to your Contact.Repository and update
the model using a database to add database tables.

You will have the following edmx as the designer view:
Look at the above object, every object has been created with their associated objects which are called Navigation Properties. Now adding
a reference Contact.Repository to the web project, you can start development. But the initial intention was to make a Repository layer over the Entity Data Model to access
the database from the web project or the business logic layer. This example does
not have any business logic layer because it is a short example but it’s a good practice to separate the business logic layer.
Add the below class to your Contact.Repository class as well as its required interfaces.
Fig: Interface and class diagram given for EntityFramework Repository
The Base Repository class implements the interface and defines those methods to manipulate data accessibility.
public class BaseRepository<T> : IBaseRepository<T>
where T : class
{
private readonly IUnitOfWork _unitOfWork;
internal DbSet<T> dbSet;
public BaseRepository(IUnitOfWork unitOfWork)
{
if (unitOfWork == null) throw new ArgumentNullException("unitOfWork");
_unitOfWork = unitOfWork;
this.dbSet = _unitOfWork.Db.Set<T>();
}
public T Single(object primaryKey)
{
var dbResult = dbSet.Find(primaryKey);
return dbResult;
}
public T SingleOrDefault(object primaryKey)
{
var dbResult = dbSet.Find(primaryKey);
return dbResult;
}
public bool Exists(object primaryKey)
{
return dbSet.Find(primaryKey) == null ? false : true;
}
public virtual int Insert(T entity)
{
dynamic obj= dbSet.Add(entity);
this._unitOfWork.Db.SaveChanges();
return obj.Id;
}
public virtual void Update(T entity)
{
dbSet.Attach(entity);
_unitOfWork.Db.Entry(entity).State = EntityState.Modified;
this._unitOfWork.Db.SaveChanges();
}
public int Delete(T entity)
{
if (_unitOfWork.Db.Entry(entity).State == EntityState.Detached)
{
dbSet.Attach(entity);
}
dynamic obj=dbSet.Remove(entity);
this._unitOfWork.Db.SaveChanges();
return obj.Id;
}
public IUnitOfWork UnitOfWork { get { return _unitOfWork; } }
internal DbContext Database { get { return _unitOfWork.Db; } }
public Dictionary<string, string> GetAuditNames(dynamic dynamicObject)
{
throw new NotImplementedException();
}
public IEnumerable<T> GetAll()
{
return dbSet.AsEnumerable().ToList();
}
}
}
In this class, the IUnitOfWork interface is used to maintain transactions during data insertion or update.
IUnitOfWork contains two methods, Commit() and StartTransaction(), which will be implemented
by the UnitOfWork class. This class will be responsible for providing the DbContext or Transaction context to start and commit the transaction.
Using the BaseRepository<T> class, you will be working with the Contact, Address entities. In EF, you will have entities according to relationships in
the DB. Those entities are also called models. Sometimes the entity models are called data models. Business models and data models always need not be the same. For view purposes,
a ViewModel should be used.
Now you will create two repository classes that inherit the BaseRepository class. These repository class instances will be communicating between
the database layer and the business logic layer/Controller (in this example).
Let's start to create a ContactRepository...
public class ContactRepository: BaseRepository<Contact>
{
public ContactRepository(IUnitOfWork unit):base(unit)
{
}
}
Address class’ repository looks like:
public class AddressRepository : BaseRepository<Address>
{
public AddressRepository(IUnitOfWork unit)
: base(unit)
{
}
}
Now from the controller class, you can call the above two repository classes in the following way:
public class ContactController : Controller
{
private IUnitOfWork uow = null;
private ContactRepository repo = null;
public ContactController()
{
uow = new UnitOfWork();
repo = new ContactRepository(uow);
}
public ActionResult Index()
{
var contacts = repo.GetAll();
return View(contacts.ToList());
}
public ActionResult Details(int id = 0)
{
Contact contact = repo.SingleOrDefault(id);
if (contact == null)
{
return HttpNotFound();
}
return View(contact);
}
public ActionResult Create()
{
return View();
}
[HttpPost]
public ActionResult Create(Contact contact)
{
if (ModelState.IsValid)
{
repo.Insert(contact);
return RedirectToAction("Index");
}
return View(contact);
}
public ActionResult Edit(int id = 0)
{
Contact contact = repo.SingleOrDefault(id);
if (contact == null)
{
return HttpNotFound();
}
return View(contact);
}
[HttpPost]
public ActionResult Edit(Contact contact)
{
if (ModelState.IsValid)
{
repo.Update(contact);
return RedirectToAction("Index");
}
return View(contact);
}
public ActionResult Delete(int id = 0)
{
Contact contact = repo.SingleOrDefault(id);
if (contact == null)
{
return HttpNotFound();
}
return View(contact);
}
[HttpPost, ActionName("Delete")]
public ActionResult DeleteConfirmed(int id)
{
Contact contact = repo.SingleOrDefault(id);
repo.Delete(contact);
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
uow.Dispose();
base.Dispose(disposing);
}
}
You have to build the UnitOfWork class by implementing IUnitOfWork and this class will be responsible for creating the EF (look at the attached code). Then the repository class (ContactRepository) will be initialized with
the uow object.
Look at the above controller. The related repository object and unitOfWork is created to access
the database using its base class' methods.
Conclusion
Using the Repository pattern, we get the advantage of isolating the data layer from
the logical layer. If the architect of an application wants to change his ORM/data storage system, then he need not worry about the business logical layer’s code. Though implementing
Repository pattern is a good approach to build your application, the Repository class is a little bit slower than
the direct use of a data access layer.