带有存储库和实体框架的UnitOfWork

时间:2019-01-10 13:52:29

标签: c# asp.net unity-container repository-pattern unit-of-work

我正在使用Entity Framework进行项目,其中我已经实现了存储库模式和DI(Microsoft Unity),现在要维护数据库事务,我想实现UnitOfWork模式,但是我对如何实现它感到完全困惑在我当前的项目中,我在Google上搜索了几篇文章,但找不到与我现有项目可行的任何内容。

下面是EF和存储库结构以及DI(Microsoft Unity)。

实体:

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>{}

接口:

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){}
        }

接口实现:

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

Global.asax中的依赖项注入设置。

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.
        }
    }

现在在我的主要网页(ASP.Net)

{{1}}

3 个答案:

答案 0 :(得分:2)

EntityFramework的DbContext已经实现了工作单元,因此没有必要再添加另一个抽象层来实现这一点。

甚至在使用Entity Framework时,甚至可能会怀疑创建Repository模式是否真的有用。除了使用分层架构和存储库之外,您还可以调查使用切片更好的架构并直接使用DbContext是否更好。

而且,仅将调用委托给实体框架DbContext的“通用Dao”有什么好处?这只是又一个抽象层次,它增加了额外的复杂性,但却没有给您带来任何附加价值。

答案 1 :(得分:0)

工作单元将数据库操作封装在一个对象中,并对其进行跟踪。在实体框架中,DbContext实现此行为,而DbSet<>实现存储库。人们之所以创建自己的包装器,是为了能够将Entity Framework换成另一个ORM,或者能够模拟Entity Framework进行测试。

答案 2 :(得分:0)

UnitOfWork模式与实体框架一起使用。

存储库和工作单元模式旨在在应用程序的数据访问层和业务逻辑层之间创建一个抽象层。实施这些模式可以帮助您的应用程序与数据存储区中的更改隔离开来,并可以促进自动化的单元测试或测试驱动的开发(TDD)。

第一步是创建存储库。存储库是一个将方法公开给业务层的类

第二步:您可以如下所示创建UnitOfWork实现。有对应于每个存储库的属性。然后,在业务层中注入工作单元以使用存储库方法。

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;
        }
    }

}

请参考文档: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