我正在为我的应用程序开发通用存储库,在这里我有一些疑问。
这是我为通用存储库准备的一些代码:
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/