代码之家  ›  专栏  ›  技术社区  ›  Gavin

将nhibernate用于存储库模型的最佳方法

  •  8
  • Gavin  · 技术社区  · 15 年前

    我有一个存储库类,它定义了一些基本的get/save/delete方法。在这些内部,我使用nhibernate对我的业务实体进行工作。例如:

    Public Class SecurityRepositoryNHibImpl : Implements ISecurityRepository
        Public Function GetUser(ByVal UUID As System.Guid) As Entities.User Implements ISecurityRepository.GetUser
            Dim eUser As Entities.User
            Using session As ISession = NHibernateHelper.OpenSession()
                eUser = session.Get(Of Entities.User)(UUID)
            End Using
            Return eUser
        End Function
    End Class
    

    但是,在我的用户类中,我有一些其他对象的属性和集合,理想情况下,我希望被懒惰地加载。但是,当然,ISession是在存储库中创建和处理的,我猜这就是为什么在尝试访问这些属性时出现“无法初始化代理-无会话”错误的原因。

    那么,我唯一的选择是在使用存储库时禁用延迟加载吗?或者是否有可能(或者只是愚蠢地)以某种方式将会话引入业务层的范围?

    我确实喜欢知识库模型,而且nhibernate在我的基础上不断增长(在尝试使其工作时经历了很多最初的挫折之后),那么您的古鲁们发现如何将它们一起使用最好呢?

    我对NHibernate和存储库模型非常陌生(在工作中,我们仍然主要使用vb6!)所以请原谅什么是愚蠢的问题。谢谢。


    @穆迪:谢谢,伙计,这真的很有帮助,但我可能会把它再打开一点。它是WCF Web服务的后端,所有的函数都是每个调用上下文,所以每个调用会话的生命周期是好的。只是不知道如何在业务层中实现这样的功能,理想情况下,我不希望业务对象必须直接与任何NHibernate类交互。我想某种包装物至少可以把它抽象出来… 嗯,你至少让我走上了正轨。


    看起来这里的关键词是“工作单元”,对于它来说,网络上存在着大量与NHibernate相关的资源。尤其是寻找 Ayende's implementation 在Rhino Commons和他的应用架构网络广播中 (no. 9 at Hibernating Rhinos) 非常有用。最初我很困惑,因为我虽然将“工作单元”放在业务层中是混合关注点, but I was soon corrected.

    1 回复  |  直到 15 年前
        1
  •  12
  •   mookid8000    14 年前

    创建您的ISession并在您的存储库中显式地处理它,这对于小型和非常简单的项目来说是可以的——但是,正如您发现的,当您开始想要使用NHibernate支持的一些酷功能时,这是很短的。

    您可能应该让会话的生活方式由存储库之外的某个内容控制—例如,如果您正在执行ASP.NET Web应用程序,则可能希望在当前请求中保存会话。( HttpContext.Current.Items 如果我调用正确),在Web请求的持续时间内,然后在请求结束时提交和处理(如果发生异常,则回滚)。

    我不知道在ASP.NET应用程序中控制会话生活方式的最佳方法,但是必须有某种方法可以在每个请求的开始和结束时调用代码。在ASP.NET MVC中,可以通过从重写其 OnActionExecuting OnActionExecuted 方法。