问题描述
我想做这样的事情...
I want to do something like this...
return GetSession()
.ToPagedList<Employee>(page, pageSize,
x=> x.SetFetchMode(DomainModelHelper.GetAssociationEntityNameAsPlural<Team>(), FetchMode.Eager));
但是我不知道如何将此Func<ICriteria,ICriteria>
传递到ISession
或ICriteria
.
But I don't know how to pass this Func<ICriteria,ICriteria>
into the ISession
or ICriteria
.
我有一个标准的分页扩展方法,并且此扩展方法应该有一个重载,在这里我可以传递其他ICriteria方法,以便可以附加地设置FetchMode
或其他内容.
I have a standard paging extension method and this extension method shall have an overload where I can pass additional ICriteria methods, so that I can additionally set up the FetchMode
or something else.
扩展方法:
public static class CriteriaExtensions
{
public static PagedList<T> ToPagedList<T>(this ISession session, int page, int pageSize) where T : Entity
{
var totalCount = TotalCount<T>(session);
return new PagedList<T>(session.CreateCriteria<T>()
.SetFirstResult(pageSize * (page - 1))
.SetMaxResults(pageSize * page)
.Future<T>().ToList(), page, pageSize, totalCount);
}
public static PagedList<T> ToPagedList<T>(this ISession session, int page, int pageSize, Func<ICriteria, ICriteria> action) where T : Entity
{
var totalCount = TotalCount<T>(session);
...
}
private static int TotalCount<T>(ISession session) where T : Entity
{
return session.CreateCriteria<T>()
.SetProjection(Projections.RowCount())
.FutureValue<Int32>().Value;
}
}
没有过载,它将看起来像这样:
Without an overload it would look like this:
return GetSession()
.CreateCriteria<Employee>()
.SetFetchMode(DomainModelHelper.GetAssociationEntityNameAsPlural<Team>(), FetchMode.Eager)
.ToPagedList<Employee>(page, pageSize);
扩展方法:
public static class CriteriaExtensions
{
public static PagedList<T> ToPagedList<T>(this ICriteria criteria, int page, int pageSize) where T : Entity
{
var copiedCriteria = (ICriteria) criteria.Clone();
var totalCount = TotalCount(criteria);
return new PagedList<T>(copiedCriteria
.SetFirstResult(pageSize * (page - 1))
.SetMaxResults(pageSize * page)
.Future<T>().ToList(), page, pageSize, totalCount);
}
private static int TotalCount(ICriteria criteria)
{
return criteria
.SetProjection(Projections.RowCount())
.FutureValue<Int32>().Value;
}
}
线路var copiedCriteria = (ICriteria) criteria.Clone();
在这里闻起来,但我不知道如何更改.
The line var copiedCriteria = (ICriteria) criteria.Clone();
smells here, but I don't know how to change this.
您会建议哪种方法?
推荐答案
有点晚了,但是,嘿!
最简单的方法是扩展IQueryOver而不是ICriteria,如下所示:
The easiest thing to do is to extend IQueryOver instead of ICriteria, like so:
public static PaginatedList<T> Paginate<T>(this IQueryOver<T, T> instance, int page, int pageSize) where T : Entity {
var countCriteria = instance.ToRowCountQuery();
var totalCount = countCriteria.FutureValue<int>();
var items = instance.Take(pageSize).Skip((page- 1)*pageSize).List<T>();
return new PaginatedList<T>(items, page, pageSize, totalCount.Value);
}
这将允许您进行所有急切的提取操作(它们将在行计数查询中删除,但条件将保持不变).示例:
This will allow you to do all your eager fetching (they will be removed in the row count query, but the criterias will remain the same). Example:
session.QueryOver<Customer>()
.Where(x => x.Status == CustomerStatus.Preferred)
.Fetch(x => x.Orders).Eager
.Paginate(1, 10);
将产生两个sql查询,如下所示:
Will yield two sql queries, like this:
对于所有项目:
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;
这篇关于NHibernate-使用ICriteria和可选的ICriteria调用进行分页的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!