【问题标题】:Unit of Work and Repository Pattern工作单元和存储库模式
【发布时间】:2015-07-16 21:19:25
【问题描述】:

我想在我的应用程序中实现简单的 IGenericRepository 和 IUnitOfWork 接口,但我不确定最好的方法是什么。

据我所知,UnitOfWork 应该用于写入,而 Repository 应该用于读取。我遇到过一种架构,我真的很喜欢它,但我只找到了接口而不是实现,我不知道我应该如何实现这些。

public interface IGenericRepository : IDisposable
{
    IUnitOfWork CreateUnitOfWork();
    T FirstOrDefault<T>(Expression<Func<T, bool>> predicate) where T : class, IBaseEntity;
    IQueryable<T> Get<T>(Expression<Func<T, bool>> predicate = null, Func<IQueryable<T>, IOrderedQueryable<T>> sorter = null, params string[] includeProperties) where T : class, IBaseEntity;
    IQueryable<T> GetAll<T>() where T : class, IBaseEntity;
    IDbContext GetDbContext();
}

public interface IUnitOfWork : IDisposable
{
    int Commit();
    bool Delete<T>(T entity) where T : class, IBaseEntity;
    int DeleteItems<T>(IList<T> entities) where T : class, IBaseEntity;
    bool Insert<T>(T entity) where T : class, IBaseEntity;
    int InsertItems<T>(IList<T> entities) where T : class, IBaseEntity;
    bool Update<T>(T entity) where T : class, IBaseEntity;
    int UpdateItems<T>(IList<T> entities) where T : class, IBaseEntity;
}

我不确定这些应该如何工作。我应该在存储库中使用 IDbContextFactory 在 Repository 和 UnitOfWork 之间共享 DbContext 还是它们应该有单独的 DbContexts?如果我实现 UnitOfWork 用于写入和 Repository 用于读取,是否应该有 UnitOfWorks DbContext 用于写入和 Repositorys DbContext 用于读取,或者它们应该共享相同的 DbContext?

我非常感谢 DbContext 和 UnitOfWork/Repository 应该如何工作的很好的解释。

这些将在服务中以这种方式实现:

public CustomerService(IGenericRepository repository)
{
    this.repository = repository;
    this.context = this.repository.GetDbContext();
}

public void UpdateCustomer(Customer customer)
{
    var uow = this.repository.CreateUnitOfWork();
    uow.AddForSave(customer);
    uow.Commit();
}

public List<Customer> GetAll()
{
    return this.repository.GetAll<Customer>();
}

任何关于 DbContext 和 UoW/Repository 关系的帮助、解释或类似于此实现的优秀教程都会有所帮助。

问候。

【问题讨论】:

  • UnitOfWork should be used for writing, while Repository should be used for reading我没听说过
  • 不应该作为“必须”,但建议用于许多实体更新(可以使用存储库更新单个实体)。虽然有很多很好的模式可以同时使用存储库,但我想坚持使用这个。
  • @Disappointed 为您提供了一个很好的链接。但请注意,UoW 和存储库模式备受争议,有些人会说已弃用。当然在 EF/MVC 环境中,DbContext 和 DbSet 已经实现了大部分功能。
  • UoW 和存储库模式的(主要)目的是将数据访问实现与应用程序的其余部分分离。此处介绍了将这些模式与 EF 结合使用的非常好的观点:stackoverflow.com/a/21361903/1942895
  • 这是一个很好的阅读链接。但我注意到那个答案是那边的少数派观点。

标签: c# asp.net-mvc entity-framework repository unit-of-work


【解决方案1】:

我建议您避免使用存储库模式进行插入/更新。

您应该考虑“命令/查询对象”作为替代方案,您可以在这方面找到一堆有趣的文章,但这里有一篇不错的:

https://rob.conery.io/2014/03/03/repositories-and-unitofwork-are-not-a-good-idea/

您将坚持每个命令使用单个命令对象以启用简单事务,避免对工作单元模式的复杂性的需求。

但是,如果您认为每个查询一个 Query 对象是多余的,这通常是正确的。相反,您可以选择从“FooQueries”对象开始,它本质上是一个存储库,但仅用于查询。 'Foo' 可能是 DDD 意义上的“域聚合”。

稍后,如果您想通过属性添加横切关注点,您可能会发现拆分单个查询对象是值得的,您甚至可以将查询对象馈送到管道中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-27
    • 2016-05-10
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    • 2011-08-28
    相关资源
    最近更新 更多