【问题标题】:nhibernate paging with detached criteria具有分离标准的休眠分页
【发布时间】:2011-06-23 11:10:30
【问题描述】:

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

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 变量中。

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

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

谢谢

【问题讨论】:

    标签: c# nhibernate


    【解决方案1】:

    根据上面的两个答案,我创建了这种使用分离条件进行分页搜索的方法。 基本上我只是采用一个普通的分离标准,在我从会话中创建了真正的 ICriteria 之后,我将它转换为 rowcount 标准,然后对它们都使用 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;
            }
        }
    

    【讨论】:

      【解决方案2】:

      我是这样做的,在用于分页条件访问的类中:

          // 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 实例。

      【讨论】:

        【解决方案3】:

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

        DetachedCriteria countSubquery = NHibernate.CriteriaTransformer.TransformToRowCount(subquery)
        

        这当然会导致对数据库的第二次调用

        【讨论】:

        • 哇,从来不知道这个。最重要的是它还会清除您可能设置的所有 FirstResult/MaxResults。
        【解决方案4】:

        【讨论】:

        • @czurski 特别查看第二个答案,因为它显示了如何在 MultiCriteria 中组合两个查询,这将减少开销。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-29
        • 1970-01-01
        相关资源
        最近更新 更多