我建立一个ASP.NET MVC 3应用程序,我已经有了一个模型,看起来像这样:错误显示的详细信息(例如ObjectContext的已配置)
public partial class Flavor
{
// ...
public string Name { get; set; }
public bool HasNuts {get; set; }
public virtual ICollection<SaleData> Sales {get; set;}
// ...
}
从一个获取一些数据DB这样:
public PartialViewResult Details(int id)
{
using (var db = new IceCreamDBFlavors())
{
Flavor someFlavor = db.Flavors.Find(id);
someFlavor.Sales = db.Sales.Where(c => c.FlavorID == id).ToList();
return PartialView("details", someFlavor);
}
}
在视图上我做这样的事:
<fieldset>
<legend>Sales Data</legend>
@foreach (var sale in Model.Sales)
{
<div>Weekly</div>
<div>@sale.Weekly</div>
}
</fieldset>
如果我不获取销售数据,我的Flavor数据显示正常,没有错误,但添加调用以检索销售数据列表会导致错误“ObjectContext实例已被处置,不能再用于需要连接的操作。”发生。
我读了一些关于此的其他文章,并猜测我错过了这里的东西。我相信这个错误是由于懒惰加载,至少根据我在这里和其他地方阅读的内容。在返回PartialView并检查对象之前,在Controller中设置一个断点,我相信会导致评估发生,因此所有内容都按照我的意愿显示。
我的印象是,ToList()
调用会强制Sales集合被填充。由于我没有问题,当该行被注释掉时,我认为问题仍然与此相关,当View正试图迭代销售,它不能。我在这里纠正?我想我想到我正在强制评估。我该如何解决这个问题?
谢谢!这解决了这个问题。我想我需要重新检查*为什么IceCreamDBFlavors需要更长的使用寿命。 – itsmatt
@itsmatt没问题,这一个也抓到我了。它需要更长的生命周期,因为现有的using语句处理了对象上下文,稍后在相同的请求中(在视图中),延迟加载需要再次使用对象上下文深入到数据中。您可以在请求结束时使用一些处理对象上下文的逻辑。 – Swaff
不,不,不,这是不好的,以及永远不应该将它变成生产系统的代码类型!你基本上说在视图中运行SQL是可以的,并且打开SELECT N + 1问题的所有可能性。 – jfar