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

这是我为通用存储库准备的一些代码:

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条记录就获得100,000条记录。我的问题是,此“逻辑”应在存储库中还是在服务中,即该服务获取所有数据,然后跳过/获取,但是需要它还是存储库已经只返回服务将需要的数据?还是应该将这些类型的方法放在继承通用方法的特定存储库中?

提前致谢

最佳答案

永远不要返回IQueryable,因为它是ORM的实现细节,并且破坏了使用存储库的精神:告诉存储库您想要从存储库中获得什么,而不是从存储库中获得什么。 IQueryable意味着您自己构建查询的一部分,从而告诉它如何进行。

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

关于分页,只需将'skip'和'take'参数传递给repo方法,即使您不使用ORM也可以使用;回购将根据用于db的DAO实现分页。为了您自己的利益,请尝试使用CQRS思维方式,这将使您的DDD生活变得更加轻松。

关于c# - 通用存储库问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19713468/

10-17 01:22