3

近一年后,我开始一个新的mvc项目,这次是版本4.我想知道以下存储库模式的实现是否比优点更多的缺点。存储库模式+工作单元

public interface IRepository<T> where T : class 
{ 
    IEnumerable<T> GetAll(); 

    IQueryable<T> Query(Expression<Func<T, bool>> filter); 

    void Add(T entity); 

    void Remove(T entity); 
} 

public interface IUnitOfWork 
{ 
    void Commit(); 
} 

public interface IDbContext : IDisposable 
{ 
    IDbSet<T> Set<T>() where T : class; 

    int SaveChanges(); 
} 

public class DbContextAdapter : IDbContext 
{ 
    private readonly DbContext _myRealContext; 

    public DbContextAdapter() 
    { 
     this._myRealContext = new EstafaContext(); 
    } 

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

    public IDbSet<T> Set<T>() where T : class 
    { 
     return _myRealContext.Set<T>(); 
    } 

    public int SaveChanges() 
    { 
     return _myRealContext.SaveChanges(); 
    } 
} 

public class SqlRepository<T> : IRepository<T> where T : class 
{ 
    private IDbSet<T> _dbSet; 

    public SqlRepository(IDbContext dbContext) 
    { 
     this._dbSet = dbContext.Set<T>(); 
    } 

    public IEnumerable<T> GetAll() 
    { 
     return this._dbSet.ToList(); 
    } 

    public IQueryable<T> Query(Expression<Func<T, bool>> filter) 
    { 
     return this._dbSet.Where(filter); 
    } 

    public void Add(T entity) 
    { 
     this._dbSet.Add(entity); 
    } 

    public void Remove(T entity) 
    { 
     this._dbSet.Remove(entity); 
    } 
} 

public class SqlUnitOfWork : IDisposable, IUnitOfWork 
{ 
    private IDbContext _dbContext; 

    private SqlRepository<Cliente> _clientes ; 

    public SqlUnitOfWork() 
    { 
     this._dbContext = new DbContextAdapter(); 
    } 

    public void Dispose() 
    { 
     if (this._dbContext != null) 
     { 
      this._dbContext.Dispose(); 
     } 
     GC.SuppressFinalize(this); 
    } 

    public IRepository<Cliente> Clientes 
    { 
     get { return _clientes ?? (_clientes = new SqlRepository<Cliente>(_dbContext)); } 
    }  

    public void Commit() 
    { 
     this._dbContext.SaveChanges(); 
    } 
} 

这样我就可以通过SqlUnitOfWork从单一点管理所有存储库。 我在之前的项目中使用过这种设计,效果很好,但我觉得效率不高,也许是多余的。 值得添加这样一个抽象层吗?

在此先感谢!

+0

[实现存储库,返回从EF实体映射的域模型]的可能副本(http://stackoverflow.com/questions/13387858/implementing-a-repositoryt-that-returns-a-domain-model -def-from-ef-entit) – jgauffin

+0

你也可以在这里阅读我的答案:http://stackoverflow.com/questions/10190384/repository-pattern-implementation/10190432#10190432 – jgauffin

回答

1

虽然我的实现并不完全像你一样,但对我来说似乎非常稳固。

其他唯一的变化我通常做的是定义特定的接口为每个实体类型库中,像这样:

public interface IClienteRepository : IRepository<Cliente> 
{ 
    IEnumerable<Cliente> GetByName(string firstName); 
    // etc 
} 

这样,我仍然可以使用所有存储库统称为我的CRUD操作,但我也可以使用同一个存储库来抽象出一些查询逻辑。您的存储库的用户应该只需知道他们想要什么,而不知道如何获取它。

这当然有点乏味,需要你制作具体的存储库实现来增加额外的功能,但它只是封装了你在应用程序中任何地方都有的查询逻辑。

+0

thx @armen,我看到你的观点。所以,无论何时我需要一些数据对象的缩减集合,最好是有一个特定的类型库实现。 – n3k

1

我不知道它是否有更多的缺点或优点,但多年来,我发现这种类型的存储库模式越来越少用。除非动态地切换数据库或数据源是一种真正的可能性,否则如果您需要一些疯狂的模拟宇宙测试覆盖率,我认为它比它的价值更麻烦。

只是我的个人喜好,但我喜欢我的数据访问方法更明确一点。例如,如果我将模型返回到视图,他们肯定会看起来不同于我的数据库中的表。所以我想要一个GetAllModelX方法,而不是GetAllDbTableRows方法。

那么这个转换代码要放在哪里?在控制器中?另一个将实体转换为模型的数据访问层?有没有对错的答案?可能不会。

我绝对在这里扮演魔鬼的拥护者,但以我的经验,我已经摆脱了这个通用的存储库设计,转而使用返回/接受模型的数据访问层,并处理所有的查询/ CRUDding/UnitOfWork通常使用EF来针对数据库。但是,再次,我是一个经典的单元测试人员,他不会做太多的嘲讽,并且会进行更多的集成测试。

+0

虽然我同意尽可能多地将工作小镇推向“层级”,但是“服务”层不是与您的存储库/实体进行交互以及构建域级模型的理想场所吗?当然是 –

+0

。但是如果你所有的版本库都保存了一个客户端而不必显式编写'SaveChanges()'你真的在做什么?写100行代码,以免你写20行后?我发现你经常会遇到这样的存储库,因为它打破了“工作单元”这个名称的灵活性 – Didaxis

+0

我还应该指出,我通常处理大型事务,而我的数据访问操作从来没有像简单的做法是直接添加/更新数据库。所以显然这样一个简单的存储库对像我这样的人没有什么好处。这种类型的设计绝对有案例,但即使在简单的网站场景中,我发现它通常是过度杀伤 – Didaxis

相关问题