简体   繁体   中英

UnitOfWork with Repository and Entity Framework

I am working on a project with Entity Framework where i have implemented Repository pattern and DI (Microsoft Unity), now to maintain the database transactions i want to implement the UnitOfWork pattern, but i am totally confused about how shall i implement it in my current project, i google around few posts, but could not find anything doable with my existing project.

Below is the EF and Repository structure along with DI (Microsoft Unity).

Entities:

public class GenericDo 
        {
            public DateTime CreatedDate {get;set;}
            public string CreatedBy {get;set;}
        }
    public class UsersDo : GenericDo
        {
            public int UserId {get;set;}
            public string Username {get;set;}
            ....
        }
    public class UserProfileDo : GenericDo
        {
            public int Id {get;set}
            public int UserId {get;set;}
            public string Address {get;set;}
            ....
        }

Interface:

public interface IGenericDao : IGenericDao<GenericDo> {}
    public interface IGenericDao<T> 
    {
        void Add(T entity);
        T Get(object Id);
        ....
    }
public interface IUsersDao : IUsersDao<UsersDo> {}
public interface IUserProfileDao : IUserProfileDao<UserProfileDo>{}

Interface Implementation:

public class GenericDao<T> : IGenericDao<T> where T : class
        {
            private readonly DataContext context;
            public GenericDao(DataContext _context)
            {
                this.context = _context;
            }
            public void Add(T entity)
            {
                context.Set<T>().Add(entity);
            }
            public T Get(object Id)
            {
                return context.Set<T>().Find(Id);
            }
        }
    public class UsersDao : GenericDao<UsersDo>, IUsersDao
        {
            public UsersDao(DataContext context) : base (context){}
        }
    public class UserPorfileDao : GenericDao<UserProfileDo>, IUserProfileDao
        {
            public UserPorfileDao(DataContext context) : base (context){}
        }

Dependency Injection Setup in Global.asax.

var container = this.AddUnity();
    container.RegisterType<IUsersDao, UsersDao>();
    container.RegisterType<IUserProfileDao, UserProfileDao>();

Now in my main webpage(ASP.Net)

public partial class Default : System.Web.UI.Page
    {
        private readonly IUsersDao usersDao;
        private readonly IUserProfileDao userProfileDao;
        public Default(IUsersDao _userDao, IUserProfileDao _userProfileDao)
        {
            this.usersDao = _userDao;
            this.userProfileDao = _userProfileDao;
        }
        // Now for testing purpose, i update record.
        protected void Page_Load(object sender, EventArgs e)
        {
            UsersDo user = usersDao.Get(1);
            user.Username = "new system";

            UserProfileDo userProfile = userProfileDao.Get(1);
            userProfile.Address = "new address";

            // Now here i am confused about setting up common Save method to update database with transaction.
        }
    }

EntityFramework's DbContext already implements Unit of Work, so it is not necessary to add yet another layer of abstraction to implement this.

One could even doubt if creating a Repository pattern is actually helpful if you're using Entity Framework. Instead of using a layered architecture and using a Repository, you could investigate whether it is not better to use a more sliced architecture and use the DbContext directly.

Also, what is the benefit of having a 'Generic Dao' that just delegates calls to Entity Frameworks DbContext ? It's just yet another level of abstraction which adds extra complexity but doesn't give you any added value.

Unit of work ecapsulates the database operations in a single object and keeps track of them. In Entity Framework DbContext implements this behaviour and DbSet<> implements the repository. The reason why people create their own wrappers around is to be able to swap Entity Framework for another ORM, if needed or to mock Entity Framework for testing,.

UnitOfWork pattern is used with Entity Framework.

The repository and unit of work patterns are intended to create an abstraction layer between the data access layer and the business logic layer of an application. Implementing these patterns can help insulate your application from changes in the data store and can facilitate automated unit testing or test-driven development (TDD).

First step is to create repositories. Repository is a class which exposes methods to business layer

Second step: You can create UnitOfWork implementation as shown below. There are properties corresponding to every repository. Then you inject Unit of Work in your business layer to use the repository methods.

public class UnitOfWork : IDisposable
{
    private SchoolContext context = new SchoolContext();
    private GenericRepository<Department> departmentRepository;
    private GenericRepository<Course> courseRepository;

    public GenericRepository<Department> DepartmentRepository
    {
        get
        {

            if (this.departmentRepository == null)
            {
                this.departmentRepository = new GenericRepository<Department>(context);
            }
            return departmentRepository;
        }
    }

}

refer documentation at: https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM