NHibernate:获取任意条件查询返回的行数的通用方法

时间:2010-10-06 21:26:10

标签: nhibernate

我知道CriteriaTransformer.TransformToRowCount,但根据link和我的经验,它不适用于聚合函数(并且它们经常使用)。由于我正在为我的应用程序编写一个分页框架,因此为每个数据查询编写“count”查询会非常繁琐。
有什么想法可以如何优化?

2 个答案:

答案 0 :(得分:1)

这并不难:

private IPagedList<ProjT> FindPaged<ProjT>(DetachedCriteria criteria, int pageIndex, int pageSize, IResultTransformer resultTransformer)
{
    int firstResult = pageIndex == 1 ? 0 : (pageIndex - 1) * pageSize;

    var countCriteria = CriteriaTransformer
        .Clone(criteria)
        .SetProjection(Projections.RowCount());

    countCriteria.ClearOrders();

    IMultiCriteria multiCriteria = Session.CreateMultiCriteria();
    multiCriteria.Add(countCriteria);

    criteria.SetFirstResult(firstResult).SetMaxResults(pageSize);

    if (resultTransformer != null)
    {
        criteria.SetResultTransformer(resultTransformer);
    }

    multiCriteria.Add(criteria);

    var result = multiCriteria
        .List()
        .Cast<System.Collections.ArrayList>()
        .ToList();

    PagedList<ProjT> list = new PagedList<ProjT>(
        result[1].Cast<ProjT>().ToList<ProjT>(),
        pageIndex,
        pageSize,
        (int)result[0][0]);

    return list;
}

IPagedList是:

public interface IPagedList<T> : ICollection<T>
{
    int TotalPages { get; }
    int TotalCount { get; }
    int PageIndex { get; }
    int PageSize { get; }
    bool HasPreviousPage { get; }
    bool HasNextPage { get; }
    bool IsFirstPage { get; }
    bool IsLastPage { get; }
}

和实施:

public class PagedList<T> : List<T>, IPagedList<T>
{
    public PagedList(IEnumerable<T> source, int pageIndex, int pageSize) :
        this(source, pageIndex, pageSize, source.Count())
    { }

    public PagedList(IEnumerable<T> source, int pageIndex, int pageSize, int totalCount)
    {
        this.TotalCount = totalCount;
        this.PageSize = pageSize;
        this.PageIndex = pageIndex;

        double pc = this.TotalCount / this.PageSize;
        if (this.TotalCount % this.PageSize > 0)
        {
            pc++;
        }
        this.TotalPages = (int)pc;

        this.HasPreviousPage = (PageIndex > 1);
        this.HasNextPage = (PageIndex * PageSize) < TotalCount;
        this.IsFirstPage = (this.PageIndex == 1);
        this.IsLastPage = (this.PageIndex == this.TotalPages);

        this.AddRange(source);
    }

    public int TotalPages { get; private set; }
    public int TotalCount { get; private set; }
    public int PageIndex { get; private set; }
    public int PageSize { get; private set; }
    public bool HasPreviousPage { get; private set; }
    public bool HasNextPage { get; private set; }
    public bool IsFirstPage { get; private set; }
    public bool IsLastPage { get; private set; }
}

答案 1 :(得分:0)

这是long discussion on paging。它是oracle sql,易于遵循。从本质上讲,

  • 不要浪费周期来计算任何人都看不到的东西。
  • 只显示下一个和上一个链接。 (选择1以上,以确定是否应隐藏下一个按钮)
  • 如果您想要最后一个按钮,请在您的sql中反转order-by。

进行比较:

  • 调整google的搜索网址以获取第101页,他们会告诉您:对不起,Google不会为任何查询提供超过1000个结果。 (您要求从1001开始的结果。)