Friday, 6 January 2017

Create a Repository pattern and Unit of Work for Entity Framework in ASP.NET MVC

In this post we are going to see how to create a Repository Pattern and UnitOfWork for Entity Framework.

Repository Pattern is the pattern where common logic for different entities resides in one place, then we have to derive that common logic for each repository. Here we take a example of Employee, Department and Task Models for entity framework using this we will create a Repository pattern. Let we see one by one.


    public class Employee
    {
        public Employee()
        {
            Tasks = new List<Task>();
        }

        public string Name { set; get; }

        public int Id { set; get; }

        public int Contact { set; get; }

        public string Address { set; get; }

        public int Salary { set; get; }

        public int DepartmentId { set; get; }

        [ForeignKey("DepartmentId")]
        public virtual Department Department { set; get; }

        public virtual ICollection<Task> Tasks { set; get; }


    }

    public class Department
    {
        public int Id { set; get; }

        public string Name { set; get; }
       
        public virtual ICollection<Employee> Employees { set; get; }

    }


    public class Task
    {
        public int Id { set; get; }

        public string Name { set; get; }

        public string Description { set; get; }

        public int EmployeeId { set; get; }

        [ForeignKey("EmployeeId")]
        public virtual Employee Employee { set; get; }

    }


For the above models we have to create the EntityDbContext


    public class CompanyDbInitializer :            
           DropCreateDatabaseIfModelChanges<CompanyDbContext>
    {
        protected override void Seed(CompanyDbContext context)
        {               
            base.Seed(context);
        }
    }


    public class CompanyDbContext:DbContext
    {
        public CompanyDbContext():base("companyConnection")
        {
            this.Configuration.AutoDetectChangesEnabled = true;
            this.Configuration.LazyLoadingEnabled = true;
            Database.SetInitializer(new CompanyDbInitializer());
        }

        public DbSet<Employee> Employees { set; get; }

        public DbSet<Department> Departments { set; get; }

        public DbSet<Task> Tasks { set; get; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
        }

    }


Connection String in web.config

  <connectionStrings>
    <add name="companyConnection" 
         connectionString="Server=SQLEXPRESS;Database=EFDB;Integrated Security=true;"                 providerName="System.Data.SqlClient" />

  </connectionStrings>



Now we have to create a Generic Repository for the Context, Then we have to derive it for all respository. The Generic Repository will contain common operation like Get, GetAll, Fetch, Insert, InsertCollection, Update, Delete, DeleteCollection, SingleOrDefault, FirstOrDefault


    public interface IRepository<T>
    {
        T Get(int id);

        IEnumerable<T> GetAll();

        IEnumerable<T> Fetch(Expression<Func<T, bool>> predicate);

        void Insert(T obj);

        void InsertCollection(IEnumerable<T> collection);

        T update(T obj);

        void Delete(T obj);

        void DeleteCollection(IEnumerable<T> collection);

        T SingleOrDefault(Expression<Func<T, bool>> predicate);

        T FirstOrDefault(Expression<Func<T, bool>> predicate);


    }


    public class Repository<T> : IRepository<T> where T : class
    {
        protected DbContext context;

        public Repository(DbContext context)
        {
            this.context = context;
        }

        public void Delete(T obj)
        {
            context.Set<T>().Remove(obj);           
        }

        public void DeleteCollection(IEnumerable<T> collection)
        {
            context.Set<T>().RemoveRange(collection);
        }

        public IEnumerable<T> Fetch(Expression<Func<T, bool>> predicate)
        {
            return context.Set<T>().Where(predicate);
        }

        public T FirstOrDefault(Expression<Func<T, bool>> predicate)
        {
            return context.Set<T>().FirstOrDefault(predicate);
        }

        public T Get(int id)
        {
            return context.Set<T>().Find(id);
        }

        public IEnumerable<T> GetAll()
        {
            return context.Set<T>().ToList();
        }

        public void Insert(T obj)
        {
            context.Set<T>().Add(obj);
        }

        public void InsertCollection(IEnumerable<T> collection)
        {
            context.Set<T>().AddRange(collection);
        }

        public T SingleOrDefault(Expression<Func<T, bool>> predicate)
        {
            return context.Set<T>().SingleOrDefault(predicate);
        }

        public T update(T obj)
        {
            context.Entry<T>(obj).State = EntityState.Modified;
            return obj;
        }

    }


Now we are going to create Repository for all Entities.


    public interface IEmployeeRepository : IRepository<Employee>
    {
        IEnumerable<Task> GetTasks(int EmployeeId);
    }

    public interface IDepartmentRepository : IRepository<Department>
    {
        IEnumerable<Employee> GetEmployees(int departmentid);
    }

    public interface ITaskRepository : IRepository<Task>
    {
        Employee GetEmployee(int taskid);

    }


In each Repository we are adding individual methods which are needed for that repositories.
Now we are going to implement the Repository,


    public class EmployeeRepository : Repository<Employee>, IEmployeeRepository
    {
        public EmployeeRepository(DbContext context):base(context)
        {

        }

        public IEnumerable<Task> GetTasks(int EmployeeId)
        {
            return this.Context.Employees.Find(EmployeeId).Tasks;
        }

        public CompanyDbContext Context
        {
            get
            {
                return this.context as CompanyDbContext;
            }
        }

    }



    public class DepartmentRepository : Repository<Department>, IDepartmentRepository
    {
        public DepartmentRepository(DbContext context):base(context)
        {

        }
        public IEnumerable<Employee> GetEmployees(int departmentid)
        {
            return Context.Departments.Find(departmentid).Employees;
        }

        public CompanyDbContext Context
        {
            get { return context as CompanyDbContext; }
        }
    }



    public class TaskRepository : Repository<Task>, ITaskRepository
    {
        public TaskRepository(DbContext context):base(context)
        {

        }
        public Employee GetEmployee(int taskid)
        {
            return Context.Tasks.Find(taskid).Employee;
        }

        public CompanyDbContext Context
        {
            get
            {
                return context as CompanyDbContext;
            }
        }
    }


Unit Of Work Implementation with three repositories and Save method , once the operations are done in repository then save the changes.


    public interface IUnitOfWork:IDisposable
    {
        IEmployeeRepository Employees { get; }

        IDepartmentRepository Departments { get; }

        ITaskRepository Tasks { get; }

        int Save();

    }

    public class UnitOfWork : IUnitOfWork
    {
        private DbContext context;
   
        public UnitOfWork(CompanyDbContext context)
        {
            this.context = context;
            Departments = new DepartmentRepository(context);
            Employees = new EmployeeRepository(context);
            Tasks = new TaskRepository(context);
        }

        public IDepartmentRepository Departments
        {
            get; private set;
        }

        public IEmployeeRepository Employees
        {
            get; private set;
        }

        public ITaskRepository Tasks
        {
            get; private set;
        }

        public void Dispose()
        {
            context.Dispose();
        }

        public int Save()
        {
            return context.SaveChanges();
        }


    }


Now we are going to implement this repository in controller, We are going to create a UnitOfWork creation.


    public class HomeController : Controller
    {
        IUnitOfWork repo;

            
        public ActionResult Index()
        {
            using (repo = new UnitOfWork(new CompanyDbContext()))
            {
                Employee empl = repo.Employees.Fetch(x => x.Id == 3).FirstOrDefault();
                empl.Name = "Rajesh";
                repo.Employees.update(empl);
                repo.Save();

                repo.Employees.Delete(empl);
                repo.Save();


                Employee emp = new Employee() { Id = 102,
                                                Name = "Suresh",
                                                DepartmentId = 1
     };

                repo.Employees.Insert(emp);
                repo.Save();

                return View(empl);

            }

        }
}


In the above code we can see that the UnitOfWork have three Repository using that we can manipulate the data in the tables. If you see the database you can see the data inserted and updated.

From this post we can learn how to create a Repository pattern and Unit of  Work in Entity Framework.





No comments:

Post a Comment