如果未连接到会话,则拦截 NHibernate Lazy-Load 行为以返回 null?
这似乎应该是一件显而易见的事情,但我已经寻找答案几个小时了,但没有成功。
我使用 NHibernate 来持久化域模型,并使用一个为 ASP.NET MVC 前端提供服务的服务层(“服务层”当前只是一个标准类库,但将来可能会转换为 WCF)。 Web 应用程序请求所需的数据并指定所需的域对象上的集合,服务层接受请求,加载对象和所需的集合(使用延迟加载),然后将对象传递回使用 AutoMapper 进行转换的位置到视图模型友好的表示。
我想要做的是加载所需的集合,从会话中分离对象并将其传递到前端。但是,当 AutoMapper 尝试映射对象时,这会导致异常,因为它尝试访问尚未初始化的集合并且会话不再可用。我可以保持对象连接,但在这种情况下,AutoMapper 转换最终会导致对象上的所有属性无论如何都被延迟加载,并且如果我们沿着 WCF 路线走下去,这将不是一个选项。
我想要做的是改变这种行为,以便集合在未连接到会话时返回 null(或者更好的是空),而不是抛出异常。这是 Entity Framework V1 中的默认行为(诚然,它没有执行自动延迟加载),我之前使用过它,但我找不到在 NH 中执行此操作的方法。
有什么想法吗?我在这里走错路了吗?
编辑-为了更清楚地了解我想要实现的目标,当访问集合属性时,我想要这种行为:
连接到会话:照常延迟加载集合。
无会话:属性为 null(而不是抛出异常)
更新 - 以下 这篇文章,作者:Billy McCafferty,我成功地使用 IUserCollectionType 实现了一个解决方案,该解决方案似乎工作到目前为止。我必须创建新类型来更改未连接到会话时的行为,而不是像他那样使用提供的 PersistentGenericBag。它并不完美,需要一些非常丑陋的映射,但至少我不需要触摸我的域对象或客户端映射来使其工作。
This seems like it should be an obvious thing but I've been searching for the answer for hours now with no success.
I'm using NHibernate to persist a domain model, with a service layer that serves an ASP.NET MVC front end (the 'service layer' is currently just a standard class library but may be converted to WCF in the future). The web app asks for the data it wants and specifies the collections on the domain object that it needs, the service layer takes the request, loads the object and required collections (using lazy loading) and passes the object back where it is transformed using AutoMapper to a viewmodel friendly representation.
What I want to be able to do is load the required collections, detach the object from the session and pass it to the front end. However, when AutoMapper tries to map the object this causes a an exception because it's trying to access collections that haven't been initialized and the session is no longer available. I can leave the object connected but in this case the AutoMapper transformation ends up causing all the properties on the object to be lazy-loaded anyway and this won't be an option is we go down the WCF route.
What I want to do is alter this behaviour so that instead of throwing an exception, the collection returns null (or better yet empty) when it is not connected to a session. This was the default behaviour in Entity Framework V1 (which admittedly didn't do auto lazy loading), which I worked with previously but I can't find a way to do it in NH.
Any ideas? Am I on the wrong track here?
EDIT- To be a bit clearer on what I'm trying to achieve, when accessing a collection property I want this behaviour:
Connected to session: lazy-load collection as normal.
No session: property is null (rather than throw exception)
UPDATE - Following this post by Billy McCafferty, I've managed to implement a solution using IUserCollectionType that seems to work so far. Rather than use the provided PersistentGenericBag as he does though, I had to create new types that changed the behaviour when not connected to the session. It's not perfect and requires some very ugly mappings but at least I don't need to touch my domain objects or client mappings to get it working.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在这种情况下,最合适的解决方案可能是在 AutoMapper 中检查可延迟加载字段(如果它们确实是使用 NHibernateUtil.IsInitialized() 加载的)。但不确定如何/是否可能使 Automapper 对所有隐式属性映射使用此检查。
老问题,但这就是我们为解决同一问题所做的事情,希望如果有人偶然发现这个问题,它可以帮助您走上正确的道路。
The most appropriate solution in this case is probably to check in AutoMapper for lazy-loadable fields if they were indeed loaded with NHibernateUtil.IsInitialized(). Not sure how/if possible to make Automapper use this check for all implicit property mappings though.
Old question but this is what we did to solve the same issue, hopefully it helps to set you on correct path if somebody stumbles upon this problem.