开发者

nhibernate paging with detached criteria

I am working on an application in which I would like to implement paging. I have the following class that implements detached criteria -

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);   
        }
    }

This works fine - it returns exactly the data that I am trying to retrieve. The problem I am running into is getting the total row count for my page navigation. since I am using the setfirstresults and setmaxresults in my detached criteria, the row count is always limited to the pageSize variable tha开发者_JS百科t is coming in.

My question is this: How can I get the total row count? Should I just create another detachedcriteria to calculate the row count? If so, will that add round trips to the db? Would I be better off not using detacedcriteria and using a straight criteria query in which I can then utilize futures? Or can I somehow use futures with what I am currently doing.

Please let me know if any further information is needed.

Thanks


I do it like this, inside my class which is used for paged criteria access:

    // 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> ();

Where NumberOfItems is a property (with a private setter) inside my 'PagedCriteriaResults' class.
The PagedCriteriaResults class takes an ICriteria instance in its constructor.


you can create a second DetachedCriteria to get to row count with the build-in CriteriaTransformer

DetachedCriteria countSubquery = NHibernate.CriteriaTransformer.TransformToRowCount(subquery)

this will of course result in a second call to the db


Discussed here:

How can you do paging with NHibernate?


Drawing on the two answers above i created this method for paged searching using detached criteria. Basically i just take an ordinary detached criteria and after i've created the real ICriteria from the session, i transform it to a rowcount critera and then use Future on both of them. Works great!

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;
        }
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜