流利的NHibernate ISession Manager或同等学历

时间:2011-07-02 23:52:16

标签: c# nhibernate fluent-nhibernate

我对FNH和NH世界都很陌生,所以要温柔:P

我已经创建了一个使用FNH进行数据访问的应用程序,它在不使用延迟加载的情况下运行良好,但是一旦我启用了延迟加载,所有内容都会变成梨形(例如,当我尝试访问懒惰时,没有会话打开 - 加载属性等)。

我创建的应用程序布局到目前为止还有一个“数据库”单例,它有各种方法,如Save(),Refer()和List()。
当调用Refer()会话打开时,将检索数据并处理会话;意味着尝试从返回的对象访问延迟加载的属性时没有可用的会话。示例:Database.Refer(“username”)。Person因为延迟加载并且会话已经关闭。

我已经读过Castle有一个SessionManager可以用于这个场景但是,无论是深夜还是缺少咖啡,我似乎无法弄清楚如何连接FNH来使用这个经理,在城堡的精神中,一切都在配置文件中定义。

我错过了什么,还是不能这样做?是否还有其他会话管理员(甚至更合适的会议)?

感谢您对此事的任何帮助。

2 个答案:

答案 0 :(得分:0)

我不认为您的特定问题与SessionManager有关,因为您已经提到过您可以开始新会话并在需要时处理它。

从我对你的帖子的理解是你试图将一个实体暴露给你的视图(带有一些延迟加载的属性) - 这已经是一个坏主意,因为它会导致讨厌的LazyInitializationException(s)。 / p>

您应该考虑区分data-modeldomain model。关键概念已在此博客中描述:

Ayende @ Rahien http://ayende.com/blog/4054/nhibernate-query-only-properties

如果您说您正在编写一个非常简单的2层应用程序,那么如果您将在数据层中微观管理您的会话,那么它可能不会有害(但请记住,这不是最好的溶液)。

我还会查看提取实体的查询,因为在我看来,您正在尝试获取只是模型一部分的数据 - 在本例中为Person。这可能导致严重的问题,如n+1 selects

What is SELECT N+1?

所以一般来说,我认为你应该更多地关注应用程序中结构的方式,而不是搜索SessionManager,因为它无法解决你的所有问题。

答案 1 :(得分:0)

对于那些仍在寻找答案的人,我将与您分享我迄今所拥有的一切。

这只是我决定使用的框架的一个非常简单的概述,并且到目前为止还不是这个问题的唯一解决方案。

我的代码的基本布局如下:

     
  •      NHibernate存储库        (参考我的模型组件和UoW组件)        
               
    • 基于HibernatingRhino的Repository实现,根据我的需要进行了修改。在此处找到:http://ayende.com/Wiki/Rhino+Commons.ashx          
      public T Get(Guid Id)
      {
          return WrapUOW(() =>
          {
              using (Audit.LockAudit())
                  return (T)Session.Get(typeof(T), Id);
          });
      }
      public void LoadFullObject(T partial)
      {
          if (partial == null)
              throw new ArgumentNullException("partial");
      
          if (partial.Id == Guid.Empty)
              return;
      
          WrapUOW(() =>
          {
              using (Audit.LockAudit())
              {
                  LazyInitialiser.InitialiseCompletely(partial, Session);
              }
          });
      }
      public T SaveOrUpdate(T entity)
      {
          using (Audit.LockAudit())
          {
              With.Transaction(() =>
              {
                  Enlist(entity);
      
                  Session.SaveOrUpdate(entity);
      
                  entity.HasChanged = false;
              });
          }
      
          return entity;
      }
      protected void Enlist(T instance)
      {
          if (instance != null && instance.Id != Guid.Empty && !Session.Contains(instance))
              using (Audit.LockAudit())
              {
                  Session.Update(instance);
              }
      }
      
      
               
    •          
    • 在这里找到一个名为'Lazy Initializer for NHibernate'的简洁小助手类:http://www.codeproject.com/KB/cs/NHibernateLazyInitializer.aspx
    •          
    • 这还包含Save,Delete和LoadFullObject的扩展方法
    •          
    •          通过创建WrapUOW方法来帮助简化我的一些代码,在此程序集中略微破坏了标准             
      protected static T WrapUOW(Func action)
      {
          IUnitOfWork uow = null;
      
          if (!UnitOfWork.IsStarted)
              uow = UnitOfWork.Start();
      
          T result = action();
      
          if (uow != null)
              uow.Dispose();
      
          return result;
      }
               
    •        
      
  • NHibernate工作单位     (参考我的模型组装)     
            
    • 同样基于HibernatingRhino的UoW实现并修改为适合
    •     
      
  •   
  • 查看 - 不重要,只需要MVVM实现     
            
    • 绑定ViewModel
    • 中的值     
      
  •   
  • 模型     
            
    • 包含我的实体类和hibernate映射文件
    •     
      
  •   
  • 视图模型     
            
    • 包含两个主视图基类,ListPage和MaintenancePage
    •       
    • ListPage基类只根据我们列出的对象类型调用Repository List方法。这会加载脱水的实体列表。
    •       
    • MaintenancePage从ListPage获取实体实例,并调用Repository.LoadFullObject方法来重新水化实体以在屏幕上使用。         
                  
      • 这允许在屏幕上使用绑定。
      •           
      • 我们也可以安全地从此页面调用Repository.SaveOrUpdate方法
      •         
            
    •     
      
  •