In this tutorial, You will learn about how to Setup Generic Repository and UnitOfWork in Data Access Layer under repository pattern implementation in Asp.net MVC.
So far, we were creating several Layers but now we will see how the actual repository get setup so that we can use its predefined methods without doing any change into this. In other words, making repository more generic.
Lets have a quick review of all layers that we created in previous tutorial.
1. Web Layer is your MVC web Project
2. Business Layer consist the CRUD operation, gets data from Data Access Layer, Manipulate them and finally returns data to the Controller ( Web Layer)
3. Domain Layer consist the Domain Models or Classes that hold the data coming from Data Access Layer. Both Web and Business Layer can use domain models to exchange data.
4. Data Access Layer consist the generic repository methods (generic CRUD operation), Unit of Work( Database Context) and NON Generic repository( User defined repository).
#How to Setup Generic Repository and UnitOfWork?
Please follow below Steps
Step 1 : Adding Interface and classes into Data Access Layer
A. Add Infrastructure Folder into Repository Layer. Inside this folder we are going to place our all Generic Repository Code.
B. Add Contract folder into Infrastructure folder
C. Add two interface into Contract folder i.e IBaseRepository.cs and IUnitOfWork.csD. Add concrete classes into Infrastructure folder i.e Add BaseRepository.cs and UnitOfWork.cs
Step 2 : Add generic code into above created files.
A. IBaseRepository.cs ( Interface)
using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; namespace MVCTutorial.Repository.Infrastructure { public interface IBaseRepository<T> { /// <summary> /// Retrieve a single item by it's primary key or return null if not found /// </summary> /// <param name="primaryKey">Prmary key to find</param> /// <returns>T</returns> T SingleOrDefault(Expression<Func<T, bool>> whereCondition); /// <summary> /// Returns all the rows for type T /// </summary> /// <returns></returns> IEnumerable<T> GetAll(); /// <summary> /// Returns all the rows for type T on basis of filter condition /// </summary> /// <returns></returns> IEnumerable<T> GetAll(Expression<Func<T, bool>> whereCondition); /// <summary> /// Inserts the data into the table /// </summary> /// <param name="entity">The entity to insert</param> /// <param name="userId">The user performing the insert</param> /// <returns></returns> T Insert(T entity); /// <summary> /// Updates this entity in the database using it's primary key /// </summary> /// <param name="entity">The entity to update</param> /// <param name="userId">The user performing the update</param> void Update(T entity); /// <summary> /// Updates all the passed entities in the database /// </summary> /// <param name="entities">Entities to update</param> void UpdateAll(IList<T> entities); /// <summary> /// Deletes this entry fro the database /// ** WARNING - Most items should be marked inactive and Updated, not deleted /// </summary> /// <param name="entity">The entity to delete</param> /// <param name="userId">The user Id who deleted the entity</param> /// <returns></returns> void Delete(Expression<Func<T, bool>> whereCondition); /// <summary> /// Does this item exist by it's primary key /// </summary> /// <param name="primaryKey"></param> /// <returns></returns> bool Exists(Expression<Func<T, bool>> whereCondition); } }
B. IUnitOfWork( Interface)
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MVCTutorial.Repository.Infrastructure
{
public interface IUnitOfWork : IDisposable
{
/// <summary>
/// Return the database reference for this UOW
/// </summary>
DbContext Db { get; }
}
}
C. BaseRepository( Concrete Class)
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace MVCTutorial.Repository.Infrastructure
{
/// <summary>
/// Base class for all SQL based service classes
/// </summary>
/// <typeparam name="T">The domain object type</typeparam>
/// <typeparam name="TU">The database object type</typeparam>
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 SingleOrDefault(Expression<Func<T, bool>> whereCondition)
{
var dbResult = dbSet.Where(whereCondition).FirstOrDefault();
return dbResult;
}
public IEnumerable<T> GetAll()
{
return dbSet.AsEnumerable();
}
public IEnumerable<T> GetAll(Expression<Func<T, bool>> whereCondition)
{
return dbSet.Where(whereCondition).AsEnumerable();
}
public virtual T Insert(T entity)
{
dynamic obj = dbSet.Add(entity);
this._unitOfWork.Db.SaveChanges();
return obj;
}
public virtual void Update(T entity)
{
dbSet.Attach(entity);
_unitOfWork.Db.Entry(entity).State = EntityState.Modified;
this._unitOfWork.Db.SaveChanges();
}
public virtual void UpdateAll(IList<T> entities)
{
foreach (var entity in entities)
{
dbSet.Attach(entity);
_unitOfWork.Db.Entry(entity).State = EntityState.Modified;
}
this._unitOfWork.Db.SaveChanges();
}
public void Delete(Expression<Func<T, bool>> whereCondition)
{
IEnumerable<T> entities = this.GetAll(whereCondition);
foreach (T entity in entities)
{
if (_unitOfWork.Db.Entry(entity).State == EntityState.Detached)
{
dbSet.Attach(entity);
}
dbSet.Remove(entity);
}
this._unitOfWork.Db.SaveChanges();
}
//--------------Exra generic methods--------------------------------
public T SingleOrDefaultOrderBy(Expression<Func<T, bool>> whereCondition, Expression<Func<T, int>> orderBy, string direction)
{
if (direction == "ASC")
{
return dbSet.Where(whereCondition).OrderBy(orderBy).FirstOrDefault();
}
else
{
return dbSet.Where(whereCondition).OrderByDescending(orderBy).FirstOrDefault();
}
}
public bool Exists(Expression<Func<T, bool>> whereCondition)
{
return dbSet.Any(whereCondition);
}
public int Count(Expression<Func<T, bool>> whereCondition)
{
return dbSet.Where(whereCondition).Count();
}
public IEnumerable<T> GetPagedRecords(Expression<Func<T, bool>> whereCondition, Expression<Func<T, string>> orderBy, int pageNo, int pageSize)
{
return (dbSet.Where(whereCondition).OrderBy(orderBy).Skip((pageNo - 1) * pageSize).Take(pageSize)).AsEnumerable();
}
public IEnumerable<T> ExecWithStoreProcedure(string query, params object[] parameters)
{
return dbSet.SqlQuery(query, parameters);
}
}
}
D. UnitOfWork( Concrete Class) :
Note: In below code MVCTutorialEntitiesContainer is db context/ Connection string name. You can copy the name from App.config File.
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MVCTutorial.Repository.Infrastructure
{
public class UnitOfWork : IUnitOfWork
{
private readonly MVCTutorialEntitiesContainer _dbContext;
public UnitOfWork()
{
_dbContext = new MVCTutorialEntitiesContainer();
}
public DbContext Db
{
get { return _dbContext; }
}
public void Dispose()
{
}
}
}
What Next => In next tutorial we will learn about how to create Non Generic Repository against each entity or database class. We will also learn how to perform CRUD operation over Generic Repository
Please Like, Share and subscribe our Channel. Have a great day.
All Code Factory
- Part 11- Insert data into database
- Part 12- Server side and clientside validation
- Part 13- Insert data into multiple tables
- Part 14- Insert data into database using JQuery
- Part 15- How to create Bootstrap Popup
- Part 16- Delete operation in Asp.net MVC
- Part 17- What is Partial View in Asp.net MVC
- Part 18- How to call Partial View using JQuery
- Part 19- Difference between Html.Partial() and Html.RenderPartial()
- Part 20- AddEdit Record using Partial View
- Part 21- Layout View in Asp.net MVC
- Part 22- Style.Render and Script.Render
- Part 23 - RenderBody, RenderSection and RenderPage.
- Part 24- Divide Page into several component using Bootstrap
- Part 25- Refresh Entity framework after any modification in database table
- Part 26- Set foreign key relationnship in database tables
- Part 27- Create Rgistration Page
- Part 28- Create Login Page
- Part 29- Client Side Validation using JQuery
- Part 30- How to return multiple Model to a View (Interview)
- Part 31- How to create Dynamic Menu using Partial View
- Part 32- Preview Image Before Uploading
- Part 33- Upload and Display Image using JQuery
- Part 34-Upload Image to SQL Server and Display
- Part 35- Download Image from URL and Upload to SQL Server
- Part 36- Cascading DropdownList
- Part 37- Implement Search Functionality
- Part 38- Attribute Routing in MVC
- Part 39- How to display multiple checkbox checked data
- Part 40- How to send multiple checkbox checked value to Server
- Part 41- How to create responsive sortable Image Gallery
- Part 42 - How to implement JQuery Autocomplete Textbox
- Part 43 - How to send Emails in Asp.net MVC
- Part 44 - Integrate JQuery DataTables plugin
- Part 45 - Display record from database using JQuery Datatable
- Part 46- Add Edit Record using JQuery DataTable
- Part 47 - JQuery DataTables Server -side Processing
- Part 48 - JQuery server side processing -Search functionality
- Part 49 - Pagination using Skip and Take method
- Part 50 - Refresh DataTable After Performing Any Action
- Part 51 - Send OTP ( One Time Password ) to any mobile device
- Part 52 - How to use AutoMapper in Asp.net MVC
- Part 53 - How to use AutoMapper ForMember Method
- Part 54 - Repository Pattern - 1 - Adding Business Layer
- Part 55 - Repository Pattern - 2 - Adding Domain Layer
- Part 56 - Repository Pattern - 3 - Dependency Injection
- Part 57- Repository Pattern- 4 - Adding Data Access Layer
- Part 58 - Repository Pattern - 5 - Setting Up Generic Repository
- Part 59 - Display Record using repository pattern
- Part 60 - Add Edit Record using Repository Pattern