我正在为我的应用程序开发一个通用存储库,我在这里有一些疑问。
这是我对通用存储库的一些代码:
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条记录。我的问题是这个“逻辑”是否应该在存储库或服务中,即服务获取所有数据,然后跳过/接受它需要或者存储库已经只返回服务需要的数据?或者这些类型的方法是否应该在继承泛型的特定存储库中?
提前致谢
答案 0 :(得分:1)
永远不会返回IQueryable,因为它是ORM 的实现细节而会破坏使用存储库的精神:告诉Repo 你想要什么,而不是如何即可。 IQueryable意味着你自己构建了一部分查询,因此你告诉它如何。
通用存储库主要是反模式,因为它使用ORM entities instead of Domain entities。即使使用DOmain实体,它也只能用作域存储库,因为您需要不同的接口定义来进行查询。根据需要定义每个存储库接口。
关于分页,只需将'skip'和'take'参数传递给repo方法。即使你没有使用ORM也会工作; repo会根据它使用的DAO来实现分页。 D b。为了您自己的利益,尝试使用CQRS思维模式,它将使您的DDD生活更加轻松。