解決關於NHibernate使用ICriteria分頁時遇到的錯誤

來源:互聯網
上載者:User

  最近在做一個項目,資料庫訪問層使用了NHibernate 2.1.0,因為項目中需要使用到分頁取資料的功能,於是在Google上搜了一把如何使用NHibernate來擷取分頁資料。結果還真不少!不過除了介紹Hibernate的,差不多都千篇一律,看來不是某某高手的文章被過度轉載,就是天下文章一大抄啊。先給兩個連結大家可以看看:

http://www.cnblogs.com/scottpei/archive/2009/10/11/1580947.html

http://blog.csdn.net/loyayol/archive/2007/09/26/1802015.aspx

  既然大家都認同這個方法,偶就試試吧!

  將代碼拷貝到我的工程中,稍作修改以適應項目的需要,然後寫了一個測試頁面運行,出錯了!提示資訊是Value cannot be null. Parameter name: projections 查了一下出錯的代碼,就在crit.SetProjection(null) ;這一行。看來還不能直接傳null值進去。不清楚網上流傳的這個版本大家都試過沒有,明明就不對嘛,不過也有可能跟我所使用的NHibernate版本有關,這個可能在早期的版本中奏效吧。我也查了一下NHibernate 2.1.0的官方版本修改記錄文檔,說是對ICriteria.SetProjection()方法的參數做了一些修改。那這個問題怎麼解決呢?

  我嘗試著將這行代碼去掉,結果在最後擷取分頁資料時報SQL語句語法錯誤,仔細看了下代碼,這行的主要用途就是在通過crit.SetProjection(Projections.RowCount()).UniqueResult()方法取得總記錄數後將SetProjection()方法所附加的條件去掉,否則下面繼續使用該對象去擷取分頁資料時就會得到類似於這樣的SQL語句:

  Select Top 5 Count(*) From MyTable

  這個在資料庫中執行肯定是通不過的。看來在取得分頁資料前必須將SetProjection()方法所附件的條件清除掉,可是查看ICriteria對象下面並沒有提供這樣的方法,SetProjection()方法所附加的條件又不能簡單得去掉。後台看到一篇老外的文章,得到了一些啟發,其實我們可以將ICriteria對象Clone一份,前一個對象專門用來返回總記錄條數,Clone後的對象則專門用來取得分頁資料,這樣問題就可以完美解決了。下面是我整理後的代碼,大家可以參考下。

/// <summary>
/// Get the pagination product list.
/// </summary>
/// <param name="cateId">Product category ID.</param>
/// <param name="currentPageIndex">Current page index, begin with 1.</param>
/// <param name="pageSize">Row count per page.</param>
/// <param name="recordCount">Return the total record count from database.</param>
/// <returns>Return the paged product object list.</returns>
public List<Products> GetProducts(int? cateId, int currentPageIndex, int pageSize, out int recordCount)
{            
    ICriteria crit = Session.CreateCriteria(typeof(Products));
    // Set query condition.
    crit.Add(Restrictions.Eq("Isdisabled", true));
    if (cateId != null)
    {
        crit.Add(Restrictions.Eq("Cateid.Id", cateId));
    }

    // Copy current ICriteria instance to the new one for getting the pagination records.
    ICriteria pageCrit = CriteriaTransformer.Clone(crit);
    
    // Get the total record count
    recordCount = Convert.ToInt32(crit.SetProjection(Projections.RowCount()).UniqueResult());
                
    //Set pagination
    pageCrit.AddOrder(new Order("Createdate", false)); // Set order parameter.
    pageCrit.SetFirstResult((currentPageIndex - 1) * pageSize).SetMaxResults(pageSize);
    return pageCrit.List<Products>().ToList<Products>();
 }

  使用CriteriaTransformer.Clone()方法將ICriteria對象Clone一個副本。擷取分頁資料的邏輯仍然使用了網路上流傳的那個版本中的代碼。下面是測試代碼:

ProductBll productBll = new ProductBll();
int recordCount;
List<Products> list = productBll.GetProducts(null, 11, 5, out recordCount);

  如果沒有where條件,可以將cateId的值設為null,第二個參數為當前的頁碼,從1開始,第三個參數是每頁要顯示的資料條數,最後一個參數是out類型的,在使用前只需要定義而不必初始化,用來擷取總資料條數。  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.