我有以下看似简单的场景,但是我仍然很喜欢NHibernate。
在我的控制器上尝试加载编辑操作的以下模型时:
控制器编辑操作:
- public ActionResult Edit(Guid id)
- {
- return View(_repository.GetById(id));
- }
库:
- public SomeModel GetById(Guid id)
- {
- using (ISession session = NHibernateSessionManager.Instance.GetSession())
- return session.Get<SomeModel >(id);
- }
模型:
- public class SomeModel
- {
- public virtual string Content { get; set; }
- public virtual IList<SomeOtherModel> SomeOtherModel { get; set; }
- }
我收到以下错误:
– 以懒惰的方式初始化一个角色集合:SomeOtherModel,没有会话或会话被关闭
我在这里缺少什么?
解决方法
问题是您创建并关闭会话中您的模型GetById方法。 (使用语句关闭会话)会话在整个业务交易中必须可用。
有几种方法可以实现这一点。您可以将NHibernate配置为使用会话工厂GetCurrentSession方法。见this post on NHForge或this post on Code Project。
- public SomeModel GetById(Guid id)
- {
- // no using keyword here,take the session from the manager which
- // manages it as configured
- ISession session = NHibernateSessionManager.Instance.GetSession();
- return session.Get<SomeModel >(id);
- }
我不用这个我写了自己的交易服务,允许以下内容:
- using (TransactionService.CreateTransactionScope())
- {
- // same session is used by any repository
- var entity = xyRepository.Get(id);
- // session still there and allows lazy loading
- entity.Roles.Add(new Role());
- // all changes made in memory a flushed to the db
- TransactionService.Commit();
- }
但是,您实现它,只要业务事务(或系统功能),会话和事务应该生活。除非你不能依赖于事务隔离或者回滚整个事情。