【问题标题】:Intercepting NHibernate Lazy-Load behaviour to return null if not connected to a session?如果未连接到会话,则拦截 NHibernate Lazy-Load 行为以返回 null?
【发布时间】:2011-09-06 15:11:29
【问题描述】:

这似乎应该是显而易见的事情,但我一直在寻找答案几个小时没有成功。

我正在使用 NHibernate 来持久化一个域模型,并带有一个服务于 ASP.NET MVC 前端的服务层(“服务层”目前只是一个标准类库,但将来可能会转换为 WCF) . Web 应用程序请求它想要的数据并指定它需要的域对象上的集合,服务层接受请求,加载对象和所需的集合(使用延迟加载)并将对象传递回使用 AutoMapper 进行转换的位置到视图模型友好的表示。

我想要做的是加载所需的集合,从会话中分离对象并将其传递给前端。但是,当 AutoMapper 尝试映射对象时,这会导致异常,因为它试图访问尚未初始化的集合并且会话不再可用。我可以让对象保持连接,但在这种情况下,AutoMapper 转换最终会导致对象上的所有属性都被延迟加载,如果我们沿着 WCF 路线走,这将不是一个选择。

我想要做的是改变这种行为,这样当它没有连接到会话时,集合不会抛出异常,而是返回 null(或者更好的是空)。这是 Entity Framework V1 中的默认行为(诚然没有自动延迟加载),我以前使用过,但我在 NH 中找不到方法。

有什么想法吗?我是不是走错了路?

编辑-为了更清楚地了解我想要实现的目标,在访问集合属性时,我想要这种行为:

连接到会话:像往常一样延迟加载收集。
无会话:属性为空(而不是抛出异常)

更新 - 继 Billy McCafferty 的 this post 之后,我已经设法使用 IUserCollectionType 实现了一个解决方案,该解决方案目前似乎有效。我没有像他那样使用提供的 PersistentGenericBag,而是必须创建新类型来改变未连接到会话时的行为。它并不完美,需要一些非常难看的映射,但至少我不需要触摸我的域对象或客户端映射来让它工作。

【问题讨论】:

  • 您的意思是集合是延迟加载的,还是(也)在您的 nhibernate 映射中标记为延迟的类的属性?也许您可以发布域类和相应视图模型类的示例代码。
  • 是的,延迟加载的集合。我的域类是标准属性和集合的相当简单的组合。这些被映射到 Web 应用程序中的 DTO 类型类。一个视图模型可能由其中几个类组成。
  • 啊,好吧,我明白你的意思了。是的,你说得对,我的 DTO 不是很具体,我可以通过为每个使用场景创建一个 DTO 来避免这个问题,但这会导致很多类似的类和重复,如果可能的话,我想避免。
  • DTO 旨在为每个单独的数据传输过程专门创建。一个呼叫的输入和输出消息甚至可能有不同的 DTO!当然,您应该尽可能重用它们(Dino Esposito 甚至“允许”使用域对象,如果它们足够的话),但不要犹豫再做一些。这就是 Automapper 的用途。
  • 虽然我不同意你所说的,但这样做会使前端代码变得相当复杂,而且我有点不愿意重新构建应用程序的不相关部分以弥补持久性框架。不过,我很感谢您的意见,我并没有真正从那个角度考虑过,我肯定会考虑一下我实现域模型的方式 -> 视图模型映射。目前,虽然我可能已经找到了一种方法来实现我正在尝试使用 NHibernate 自定义集合类型,但如果我有任何问题,我会更新我的问题。

标签: c# nhibernate soa


【解决方案1】:

在这种情况下,最合适的解决方案可能是在 AutoMapper 中检查延迟加载字段,如果它们确实是使用 NHibernateUtil.IsInitialized() 加载的。不确定如何/是否可能使 Automapper 对所有隐式属性映射使用此检查。

老问题,但这是我们为解决同一问题所做的,希望如果有人偶然发现这个问题,它可以帮助您走上正确的道路。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-20
    • 1970-01-01
    • 1970-01-01
    • 2019-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多