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

Nhibernate 存储库/工作单元模式-如何查询存储库中满足特定条件的对象?,nhibernate,entity-framework,orm,repository-pattern,unit-of-work,Nhibernate,Entity Framework,Orm,Repository Pattern,Unit Of Work,我有一个C语言的标准存储库接口,其中包括以下方法: IEnumerable<T> GetAll(); T GetById(int id); void Delete(T entity); void Add(T entity); 如果我有大量的对象,GetAll会在过滤掉我不需要的对象之前返回所有对象吗?我怎样才能防止不需要的对象被返回呢 显然,我可以向接口添加更多方法,但这似乎与通过接口仅公开CRUD操作不符 i、 e.-我不认为我应该添加这样的内容,但也许我错了: IList<

我有一个C语言的标准存储库接口,其中包括以下方法:

IEnumerable<T> GetAll();
T GetById(int id);
void Delete(T entity);
void Add(T entity);
如果我有大量的对象,GetAll会在过滤掉我不需要的对象之前返回所有对象吗?我怎样才能防止不需要的对象被返回呢

显然,我可以向接口添加更多方法,但这似乎与通过接口仅公开CRUD操作不符

i、 e.-我不认为我应该添加这样的内容,但也许我错了:

IList<T> GetAllWhereMeetsMyCriteria();

不熟悉nhibernate,但通常,我会选择您的最后一个解决方案,即满足我的标准的所有地方:

有一个很好的Genric存储库,它位于:

您可能想使用它,因为它涵盖了更多的情况。此外,您还可以根据特定需要从中派生自定义存储库。例如:

更新: 您可以在派生存储库中定义自定义标准并使用它们。e、 g

private ICriteria CriteriaCategoryId(int categoryId)
    {
        ICriteria criteria = Session.CreateCriteria(typeof(Product));
        criteria.CreateCriteria("Category")
            .Add(Expression.Eq("Id", categoryId));
        return criteria;
    }  
public IList<Product> ProductByCategory(int categoryId, int pageStartRow, int pageSize)
    {
        var criteria = CriteriaCategoryId(categoryId)
            .SetFirstResult(pageStartRow)
            .SetMaxResults(pageSize);

        return criteria.List<Product>();
    }

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

要回答您的特定问题,存储库界面包含以下方法:

IEnumerable<T> GetMany(Expression<Func<T, bool>> where);    
它在RepositoryBase类中实现如下:

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

是您的GetAll。Where将把您的所有对象从数据库拉到应用程序,并对对象执行linq@Kamyar解决方案也会这样做@在我写这个答案的时候,迪马斯特提供了一个正确的解决方案

首先,您真的需要同时支持NHibernate或EF的存储库吗?这是客户的要求吗?如果不是这样,你就是在浪费资源。选择技术并创建应用程序遵循关注点分离所需的最小抽象


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

这看起来很有用,感谢so+1。我会仔细研究你的建议,如果是这样的话,我会记下答案。谢谢没问题。请注意,许多人并不直接使用通用存储库。他们从中派生自定义存储库,例如ProductRepository,并直接使用这些派生的存储库。祝你好运。请你澄清为什么是这个。Query.Wherecriteria.ToList;返回所有实体,然后对对象执行linq?我认为在我们使用ToList或等效方法之前,它不会从数据库中获取数据。会进行查询。Where first从db返回所有数据,然后执行linq?这不是客户的要求。我正在为我的MSc写一个项目,在这个项目中,我检查了实体框架的各个方面。我被要求将其与更成熟的O/RM NHibernate进行对比,以了解它们是如何相互堆叠的,因此需要同时支持这两者。谢谢您的回答。@Kamyar:ToList执行查询,但问题是您在where中使用Func而不是Expressoin。Func是IEnumerable上使用的委托,因此EF必须首先将所有实体加载到内存中才能运行委托。表达式用于IQueryable,并将其转换为SQL。这是很常见的错误。谢谢!我不知道+1.
private ICriteria CriteriaCategoryId(int categoryId)
    {
        ICriteria criteria = Session.CreateCriteria(typeof(Product));
        criteria.CreateCriteria("Category")
            .Add(Expression.Eq("Id", categoryId));
        return criteria;
    }  
public IList<Product> ProductByCategory(int categoryId, int pageStartRow, int pageSize)
    {
        var criteria = CriteriaCategoryId(categoryId)
            .SetFirstResult(pageStartRow)
            .SetMaxResults(pageSize);

        return criteria.List<Product>();
    }
IEnumerable<T> GetMany(Expression<Func<T, bool>> where);    
public virtual IEnumerable<T> GetMany(Expression<Func<T, bool>> where)
{
    return dbset.Where(where).ToList();
}