2011-04-16 33 views
3

什麼是加載集合和使用NHibernate更新所有項目的最佳方法。當前代碼加載50個對象並在其自己的事務中處理每個對象(如果1次失敗,則其他人都可以)。用NHibernate處理大量記錄

NH Profiler說每個會話都有太多的SQL查詢。

畢竟,你對這段代碼有什麼看法?

using (var session = sessionFactory.OpenSession()) 
     { 
      var myCollection = 
       (from obj in session.Query<MyObject>() 
       select obj).Take(50); 

      foreach (var item in myCollection) 
      { 
       using (var tx = session.BeginTransaction()) 
       { 
        try 
        { 
         // Do some stuff... 
         session.Update(item); 
         tx.Commit(); 
        } 
        catch (Exception) 
        { 
         tx.Rollback(); 
        } 
       } 
      } 
     } 

回答

4

NHibernate: Streaming large result sets

NHibernate的是指在一個 OLTP系統中使用,因此,它通常是在的情況下使用 這裏我們要加載的數據的 相對少量從 該數據庫,使用它並將其保存 回來。對於報告方案, 是更好的替代方案,通常情況下(和 之前你問,任何報告包 將做,工作的正確工具等)。

但有些情況下,您想要 儘可能使用NHibernate報告 的情況。也許是因爲 的報告要求不是 足以證明您有權轉到單獨的 工具,或者您想使用您已知的 。在這種情況下,你傾向於遇到問題 ,因爲你違反了建立 NHibernate時做出的假設 。

using (IStatelessSession s = sessionFactory.OpenStatelessSession()) 
{ 
    var books = new ActionableList<Book>(book => Console.WriteLine(book.Name)); 
    s.CreateQuery("from Book") 
     .List(books); 

} 

無狀態會話,不像 正常NHibernate的會議,不 跟蹤加載的對象,所以這裏的 代碼和數據讀取的代碼是 本質上是一回事。

基本上,使用無狀態會話和批處理。另請參閱:NHibernate Perf Tricks

+0

我會在星期一嘗試無狀態會話並在這裏報告... – mynkow 2011-04-16 21:07:32

+0

根據原始問題,您將如何/更新/每條記錄沒有將所有記錄同時加載到內存中? – pettys 2011-06-23 15:54:11

+0

@pettys在這種情況下,我會使用純HQL和ExecuteUpdate() - > http://docs.jboss.org/hibernate/core/3.3/reference/en/html/batch.html#batch-direct – rebelliard 2011-06-23 18:19:27

0

您有多少個查詢?也許你會遇到select N+1問題,因爲你正在爲你的「do stuff」部分中的每個對象加入懶惰屬性。嘗試加載第一個查詢時加入對象所需的所有部分。

+0

沒有選擇+1問題。我只是覺得我做錯了事情。 – mynkow 2011-04-16 21:06:58