我的工作有问题。当我们尝试从MVC3视图中访问NHibernate实体上的延迟加载属性时,将抛出“No Session”LazyInitializationException。这只是在上周开始出现在我们身上,但我们无法缩小问题的范围。看起来并不是一个简单的解决方案。
备注:
我们在这里缺少什么?
答案 0 :(得分:1)
您的实体加载模式在视图中称为开放会话,它被视为反模式。有关此模式的更多信息here和here。
推荐的方法是使用一些具有预取数据的视图模型。但是如果你不能这样做,你可以使用linq预取模型数据到nhibernate扩展扩展。有一个开源库ITDT.Sentia,它提供了类型化的扩展扩展,或者你可以在google中搜索“nhibernate expand”。有关更低级别的内容,您可以查看nhibernate fetching strategies。
例如使用ITDT.Sentia库并具有以下模型:
public class User : BaseEntity
{
public virtual string Email { get; set; }
public virtual Company Company { get; set; }
}
public class Company : BaseEntity
{
public virtual string Name { get; set; }
}
假设在获取用户后延迟加载公司实体,您可以执行以下操作:
IList<User> users = userRepository
.GetAll()
.Where(u => /*some constraints*/)
// here you are telling nhibernate to make a join and eger load what you need
.Expand(u => u.Company)
.ToList();
至于dev-environment中的不同行为,我只能猜测它是在使用其他一些配置文件,也许有不同的调试/发布web.configs?
答案 1 :(得分:0)
您是否直接绑定到视图中的对象模型?这听起来像你的问题,因为你查看直接绑定到域对象。由于域对象具有惰性集合,因此它尝试按需加载集合元素,这需要Nhibernate会话。
您应该在控制器方法中构建完整的视图模型。
我的建议是为您拥有的每个视图创建一个视图模型。然后,当您查询NHibernate时,直接投影到模型中或使用Automapper将对象模型转换为视图模型。直接投影的好处是通过nhibernate进行查询会更有效率,因为它只会选择你需要的列。
另见本文。 http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/
它是视图模型的一组创建最佳实践。