NHibernate – 使用ICriteria进行分页和可选的ICriteria调用

我想做这样的事……

return GetSession() .ToPagedList(page, pageSize, x=> x.SetFetchMode(DomainModelHelper.GetAssociationEntityNameAsPlural(), FetchMode.Eager)); 

但我不知道如何将这个Func传递到ISessionICriteria

我有一个标准的分页扩展方法,这个扩展方法应该有一个重载,我可以传递额外的ICriteria方法,这样我还可以设置FetchMode或其他东西。

扩展方法:

 public static class CriteriaExtensions { public static PagedList ToPagedList(this ISession session, int page, int pageSize) where T : Entity { var totalCount = TotalCount(session); return new PagedList(session.CreateCriteria() .SetFirstResult(pageSize * (page - 1)) .SetMaxResults(pageSize * page) .Future().ToList(), page, pageSize, totalCount); } public static PagedList ToPagedList(this ISession session, int page, int pageSize, Func action) where T : Entity { var totalCount = TotalCount(session); ... } private static int TotalCount(ISession session) where T : Entity { return session.CreateCriteria() .SetProjection(Projections.RowCount()) .FutureValue().Value; } } 

编辑:

没有过载,它看起来像这样:

 return GetSession() .CreateCriteria() .SetFetchMode(DomainModelHelper.GetAssociationEntityNameAsPlural(), FetchMode.Eager) .ToPagedList(page, pageSize); 

扩展方法:

 public static class CriteriaExtensions { public static PagedList ToPagedList(this ICriteria criteria, int page, int pageSize) where T : Entity { var copiedCriteria = (ICriteria) criteria.Clone(); var totalCount = TotalCount(criteria); return new PagedList(copiedCriteria .SetFirstResult(pageSize * (page - 1)) .SetMaxResults(pageSize * page) .Future().ToList(), page, pageSize, totalCount); } private static int TotalCount(ICriteria criteria) { return criteria .SetProjection(Projections.RowCount()) .FutureValue().Value; } } 

line var copiedCriteria = (ICriteria) criteria.Clone(); 闻到这里,但我不知道如何改变这一点。

你会建议采用哪种方法?

根据我的理解,您试图从创建它的方法之外修改标准的行为。

因此你有:

 public IList GetPageOf(int page, int pageSize, Func modifier) { return Session.CreateCriteria() .SetFirstResult(pageSize * (page-1)) .SetMaxResults(pageSize) .ToList(); } 

要为修饰符提供机会,您需要做的就是将主体更改为:

 return modifer(Session.CreateCriteria) //the modifer gets first dibs on the criteria .SetFirstResult(pageSize * (page-1)) .SetMaxResults(pageSize) .ToList(); 

请注意,在使用SetFirstResult或SetMaxResults的条件中更改多对多关系和多对一关系的提取模式可能会导致检索到错误的行数。

有点晚了,但是嘿!

最简单的方法是扩展IQueryOver而不是ICriteria,如下所示:

 public static PaginatedList Paginate(this IQueryOver instance, int page, int pageSize) where T : Entity { var countCriteria = instance.ToRowCountQuery(); var totalCount = countCriteria.FutureValue(); var items = instance.Take(pageSize).Skip((page- 1)*pageSize).List(); return new PaginatedList(items, page, pageSize, totalCount.Value); } 

这将允许您进行所有急切的提取(它们将在行计数查询中删除,但标准将保持不变)。 例:

 session.QueryOver() .Where(x => x.Status == CustomerStatus.Preferred) .Fetch(x => x.Orders).Eager .Paginate(1, 10); 

将产生两个sql查询,如下所示:

对于所有项目:

 SELECT this_.id, this_.url, order_.sum FROM Customers this_ LEFT OUTER JOIN orders order_ ON this_.id = order_.customer_id WHERE this_.status = 1 LIMIT 10; 

对于伯爵:

 SELECT count(*) as y0_ FROM Customers this_ WHERE this_.type = 1;