2013-10-31 97 views
3

我正在为我的应用程序开发通用存储库,我在这里有一些疑问。通用存储库问题

这是一些我对通用的存储库中的代码:

public interface IEntityRepository<T> where T : class 
{ 
    void Add(T entity); 
    T GetById(int id); 
    IEnumerable<T> Get(Expression<Func<T, bool>> predicate); 
    IEnumerable<T> GetAll(); 
} 

public class EntityRepository<T> : IDisposable, IEntityRepository<T> where T : class 
{ 
    protected DbSet<T> DbSet; 
    protected DbContext Context; 

    public EntityRepository(DbContext dataContext) 
    { 
     DbSet = dataContext.Set<T>(); 
     Context = dataContext; 
    } 

    public void Add(T entity) 
    { 
     DbSet.Add(entity); 
    } 

    public IEnumerable<T> Get(Expression<Func<T, bool>> predicate) 
    { 
     return DbSet.Where(predicate); 
    } 

    public IEnumerable<T> GetAll() 
    { 
     return DbSet; 
    } 

    public T GetById(int id) 
    { 
     return DbSet.Find(id); 
    } 

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

什么我遇到困难是这样的:

1 - 我应该返回的IEnumerable从仓库层服务层而不是IQueryable?我已经阅读了关于这个主题的一些关于网络的文章,但是找不到这个问题的一个明确的或合理的明确的答案。通过返回IEnumerable,所有后续查询将在本地完成?

2 - 显然需要的一件事是能够检索分页数据。我不想获得10万条记录只是为了显示50.我的问题是,如果这个“逻辑”应该在存储库或服务,即服务获取所有数据,然后跳过/需要但它需要或存储库已经只返回服务需要的数据?还是应该将这些类型的方法放在继承通用类的特定存储库中?

在此先感谢

+0

我认为回购应该尽可能愚蠢,只是一个DbSet的包装。也许这么愚蠢,你开始问自己,为什么我首先需要他们?这确实是[正在进行的辩论](http://stackoverflow.com/a/5626884/861716)。顺便说一下,在回购之外拥有DbContext是一个不错的选择。 –

回答

1

永远不会返回IQueryable的,因为它是一个ORM 失败使用资源库的精神的实现细节:告诉回购你从它想要的东西,不如何。 IQueryable意味着你自己构建查询的一部分,因此你告诉它如何

通用存储库大多是反模式,因为它使用ORM entities instead of Domain entities。即使使用DOmain实体,它也只能用作Domain Repositories,因为您需要用于查询目的的不同接口定义。根据需要定义每个存储库接口。

关于分页,只需将'skip'和'take'参数传递给repo方法。即使不使用ORM,它也会起作用,回购将根据其使用的DAO执行分页分贝。为了您自己的利益,请尝试使用CQRS思维模式,这将使您的DDD生活变得更加轻松。