我正在为学校做一些项目并遇到了一件奇怪的事情。情况是这样的:
在我的SQL Server数据库中,我有3个表:Product,Ingredient和ProductIngredient。最后一个是前两个之间的PJT。
我在控制器中有这个:
public ActionResult Index()
{
List<Product> products;
using (FastfoodConnection conn = new FastfoodConnection())
{
products = conn.Products.ToList();
}
TestModel tM = new TestModel();
tM.Products = products;
return View(tM);
}
这是我的观点:
@foreach (var product in Model.Products)
{
<tr>
<td> @product.Name</td>
<td> @product.Description</td>
</tr>
<tr>
<th>Ingredients</th>
<tr>
<tr>
<td>
<ul>
@foreach (var ingredient in product.Ingredients)
{
<li>@ingredient.IngredientName</li>
}
</ul>
</td>
</tr>
}
</table>
现在 - 当我在控制器中设置断点并逐步调试代码时,一切正常,结果显示为我想要的。但是,当我尝试运行代码(没有调试)时,我得到带有描述&#34的ObjectDisposedException; ObjectContext实例已被释放,不能再用于需要连接的操作。&#34;显然这是关于 product.Ingredients列表为null。
我的问题是:可能是什么问题以及如何解决?
答案 0 :(得分:4)
您需要急切加载Ingredients
。 EF不会尝试从数据库中获取它们,直到您需要它们,这称为延迟加载。由于您在处理完上下文后尝试访问它们,因此EF无法在数据库中查询Ingredients
并获得异常。
急切加载告诉EF它应该在获取产品时在同一个运行中获取这些实体。当您事先知道需要实体时,使用预先加载是一个好主意。这避免了多个db调用,因为在一个查询中获取所有内容。它可以通过Include(...)
方法调用:
public ActionResult Index()
{
List<Product> products;
using (FastfoodConnection conn = new FastfoodConnection())
{
products = conn.Products.Include(p => p.Ingredients).ToList();
}
TestModel tM = new TestModel();
tM.Products = products;
return View(tM);
}
这应该可以解决您的问题。另外,请确保您的产品型号中标有Ingredients
的{{1}}集合,这样可以启用延迟/急切加载,但由于它在调试模式下工作,我想这样就可以了。