2011-04-16 85 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