存储库/工作单元模式 - 如何在存储库中查询满足特定条件的对象?

JMc*_*JMc 5 nhibernate orm entity-framework unit-of-work repository-pattern

我在C#中有一个标准的存储库接口,它包括以下方法:

IEnumerable<T> GetAll();
T GetById(int id);
void Delete(T entity);
void Add(T entity);
Run Code Online (Sandbox Code Playgroud)

在我的域层,我实例化的是一个新的工作单元包装器并将其传递给存储库.工作单元包装类隐藏我是使用NHibernate还是实体框架并公开Commit()方法.

在我的域层中,如何查询仅满足特定条件的对象?

我认为我现在正在做的事情是非常低效的.我目前正在这样做:

var results = myRepository.GetAll().Where......
Run Code Online (Sandbox Code Playgroud)

如果我有大量的对象,GetAll()会在过滤掉我不需要的对象之前返回它们中的每一个吗?如何防止不需要的对象被退回?

显然我可以在接口上添加更多方法,但这似乎与仅通过接口公开CRUD操作一致.

即 - 我不认为我应该添加像(但也许我错了):

IList<T> GetAllWhereMeetsMyCriteria();
Run Code Online (Sandbox Code Playgroud)

Lad*_*nka 6

是的,您GetAll().Where将把所有对象从数据库中提取到应用程序并执行linq-to-objects.@Kamyar解决方案也会这样做.@Dysaster在我写这个答案时提供了正确的解决方案.

首先 - 你真的需要必须支持NHibernate或EF的存储库吗?是客户要求吗?如果不是,你就是在浪费资源.选择技术并创建应用程序所需的最小抽象,以便分离关注点.

如果你真的需要高级抽象和持久性API的绝对独立性,你应该使用系列中的第三个模式 - 规范模式.使用自定义规范,如果将规范描述的条件转换为数据源所需的操作,您将能够将持久性更改为任何内容.NHibernate中的Criteria API或扩展方法IQueryable都是规范,但它们依赖于技术.


vha*_*lac 4

看一下这篇博文[weblogs.asp.net] 中使用的存储库模式。我发现源代码采用了一些有趣的模式,我不断返回并再次检查。该代码实现了存储库和工作单元模式。

为了回答您的具体问题,存储库接口包含以下方法:

IEnumerable<T> GetMany(Expression<Func<T, bool>> where);    
Run Code Online (Sandbox Code Playgroud)

在类中的实现如下RepositoryBase<T>

public virtual IEnumerable<T> GetMany(Expression<Func<T, bool>> where)
{
    return dbset.Where(where).ToList();
}
Run Code Online (Sandbox Code Playgroud)

EF 和 NHibarnate 可能都有支持这种用法所需的接口。