带有分离标准的nhibernate分页

时间:2011-02-08 13:56:45

标签: c# nhibernate

我正在开发一个我希望实现分页的应用程序。我有以下类实现分离标准 -

public class PagedData : DetachedCriteria
    {
        public PagedData(int pageIndex, int pageSize) : base(typeof(mytype))
        {

            AddOrder(Order.Asc("myId"));

            var subquery = DetachedCriteria.For(typeof(mytype2))
                .SetProjection(Projections.Property("mytype.myId"));

            Add(Subqueries.PropertyIn("myId", subquery));

            SetFirstResult((pageIndex - 1) * pageSize);
            SetMaxResults(pageSize);   
        }
    }

这很好用 - 它会返回我想要检索的数据。我遇到的问题是获取页面导航的总行数。因为我在我的分离标准中使用了setfirstresults和setmaxresults,所以行计数总是限于进入的pageSize变量。

我的问题是:如何获得总行数?我应该创建另一个detachedcriteria来计算行数吗?如果是这样,那会增加到db的往返行程吗?我最好不要使用detacedcriteria并使用直接的标准查询,然后我可以利用期货?或者我可以以某种方式使用期货与我目前正在做的事情。

如果需要进一步的信息,请告诉我。

由于

4 个答案:

答案 0 :(得分:3)

我这样做,在我的班级里面用于分页标准访问:

    // In order to be able to determine the NumberOfItems in a efficient manner,
    // we'll clone the Criteria that has been given, and use a Projection so that
    // NHibernate will issue a SELECT COUNT(*) against the ICriteria.
    ICriteria countQuery = 
        CriteriaTransformer.TransformToRowCount (_criteria);

    NumberOfItems = countQuery.UniqueResult<int> ();

其中NumberOfItems是我的“PagedCriteriaResults”类中的属性(带有私人设定器)。
PagedCriteriaResults类在其构造函数中采用ICriteria实例。

答案 1 :(得分:2)

您可以创建第二个DetachedCriteria来使用内置CriteriaTransformer获取行数

DetachedCriteria countSubquery = NHibernate.CriteriaTransformer.TransformToRowCount(subquery)

这当然会导致第二次调用db

答案 2 :(得分:1)

答案 3 :(得分:0)

借鉴上面的两个答案,我使用分离标准创建了此分页搜索方法。 基本上我只是采用一个普通的独立标准,在我从会话中创建了真正的ICriteria之后,我将其转换为rowcount critera然后在它们两个上使用Future。效果很好!

public PagedResult<T> SearchPaged<T>(PagedQuery query)
    {
        try
        {
            //the PagedQuery object is just a holder for a detached criteria and the paging variables
            ICriteria crit = query.Query.GetExecutableCriteria(_session);
            crit.SetMaxResults(query.PageSize);
            crit.SetFirstResult(query.PageSize * (query.Page - 1));

            var data = crit.Future<T>();

            ICriteria countQuery = CriteriaTransformer.TransformToRowCount(crit);

            var rowcount = countQuery.FutureValue<Int32>();

            IList<T> list = new List<T>();
            foreach (T t in data)
            {
                list.Add(t);
            }

            PagedResult<T> res = new PagedResult<T>();
            res.Page = query.Page;
            res.PageSize = query.PageSize;
            res.TotalRowCount = rowcount.Value;
            res.Result = list;
            return res;
        }
        catch (Exception ex)
        {
            _log.Error("error", ex);
            throw ex;
        }
    }