通用存储库问题

时间:2013-10-31 17:53:46

标签: c# entity-framework repository repository-pattern

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

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

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 - 显然需要的一件事是能够检索分页数据。我不想只显示50条记录。我的问题是这个“逻辑”是否应该在存储库或服务中,即服务获取所有数据,然后跳过/接受它需要或者存储库已经只返回服务需要的数据?或者这些类型的方法是否应该在继承泛型的特定存储库中?

提前致谢

1 个答案:

答案 0 :(得分:1)

永远不会返回IQueryable,因为它是ORM 的实现细节而会破坏使用存储库的精神:告诉Repo 你想要什么,而不是如何即可。 IQueryable意味着你自己构建了一部分查询,因此你告诉它如何

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

关于分页,只需将'skip'和'take'参数传递给repo方法。即使你没有使用ORM也会工作; repo会根据它使用的DAO来实现分页。 D b。为了您自己的利益,尝试使用CQRS思维模式,它将使您的DDD生活更加轻松。