MVC和实体框架中的M-M关系仅在调试器模式下有效

时间:2016-01-08 09:45:45

标签: c# asp.net-mvc entity-framework

我正在为学校做一些项目并遇到了一件奇怪的事情。情况是这样的:

在我的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。

我的问题是:可能是什么问题以及如何解决?

1 个答案:

答案 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}}集合,这样可以启用延迟/急切加载,但由于它在调试模式下工作,我想这样就可以了。