【问题标题】:Lazy Loaded NHibernate entities in MVC3 viewsMVC3 视图中延迟加载的 NHibernate 实体
【发布时间】:2012-04-19 02:45:55
【问题描述】:

我们在我工作的地方遇到了问题。当我们尝试从 MVC3 视图中访问 NHibernate 实体上的延迟加载属性时,将抛出“No Session” LazyInitializationException。这只是在上周才开始出现在我们身上,但我们一直无法缩小问题的范围。不过似乎没有简单的解决方案。

注意事项

  • 堆栈跟踪示例:http://textsnip.com/613608
  • 我们不会在项目中的任何地方处理(或将会话包装在使用中)。我们让 ObjectFactory 来处理。
  • 在我们的 TeamCity 测试环境中运行回归测试(SpecFlow with WatiN)时发生。我们没有人能够在我们的开发机器上重现该问题。
  • 这也不会始终如一地发生。虽然失败的测试通常是相同的测试,但它们不会一直失败。访问会命中某些相同视图的页面的其他测试不会失败。
  • 在确实失败的测试中,它们似乎更倾向于延迟加载集合初始化而不是非集合,但两者都发生了。
  • 虽然我知道尽可能提前加载实体会更好,但由于我们的许多表模型相互依赖,目前还不是那么可行。

我们在这里缺少什么?

【问题讨论】:

  • 你能发布实体和休眠条件/查询等吗?
  • 您如何在测试中管理 ISession?

标签: asp.net-mvc-3 nhibernate


【解决方案1】:

您的实体加载模式在视图中称为开放会话,它被视为反模式。更多关于这种模式 herehere 的缺点。

推荐的方法是使用一些带有预取数据的视图模型。但是如果你做不到,你可以使用 linq 预取模型数据来休眠扩展扩展。有一个开源库ITDT.Sentia,它提供了类型扩展扩展或者你可以在谷歌中搜索“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();

至于开发环境中的不同行为,我只能猜测它以某种方式使用了其他一些配置文件,也许有不同的调试/发布 web.configs?

【讨论】:

    【解决方案2】:

    您是否直接绑定到视图中的对象模型?这听起来像您的问题,因为您查看直接绑定到域对象。由于域对象具有惰性集合,因此它会尝试按需加载集合元素,这需要 Nhibernate 会话。

    您应该在控制器方法中构建完整的视图模型。

    我的建议是为您拥有的每个视图创建一个视图模型。然后在查询 NHibernate 时,直接投影到模型中或使用 Automapper 将您的对象模型转换为视图模型。直接投影的好处是通过 nhibernate 进行查询会更高效,因为它只会选择您需要的列。

    另见这篇文章。 http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/

    这是为视图模型创建的一组最佳实践。

    【讨论】:

    • 我们很清楚,尝试在视图中使用我们的实际实体被认为是禁忌,但我们目前无法更改它。此外,这个问题最近才开始出现,几个月来一直运行良好。我们知道我们需要 NHibernate 会话,这就是我们让 ObjectFactory 根据每个请求创建它的原因,因此在视图中使用模型时它应该仍然存在。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-24
    • 1970-01-01
    • 2011-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多