【问题标题】:"DataContext accessed after Dispose" error when disposing datacontext from ActionResult method in controller ASP.NET MVC 3从控制器 ASP.NET MVC 3 中的 ActionResult 方法处理数据上下文时出现“Dispose 后访问的 DataContext”错误
【发布时间】:2011-12-23 18:36:10
【问题描述】:

这是我的代码:

public ActionResult MainMenu(int id)
{
  using (WebDataContext context = new WebDataContext())
  {
    //var dataLoadOptions = new System.Data.Linq.DataLoadOptions();
    //dataLoadOptions.LoadWith<MenuCache>(x => x.Menu);
    //context.LoadOptions = dataLoadOptions;

    var menu = context.MenuCaches
                      .AsEnumerable()
                      .Where(x => x.ID == id 
                                  && (x.Local == true || x.National == true));
    foreach (var item in menu)
    {
      if (item.Parent.Parent != null && item.Parent.ParentID == 0)
      {
        menu = item.Children;
      }
    }
    return View(menu.ToList());
  }
}

我在网上找到了一些关于如何修复它的选项。一个是做yield return View(menu));,但这给了我ActionResult is not an iterator的错误。函数中的注释代码是我发现的另一个选项,但这也不起作用。有任何想法吗?非常感谢。

【问题讨论】:

  • 我相信您的问题是,在您的视图中,您正在访问“MenuCache”的属性,该属性是一个实体,并且在处理数据上下文之前未加载。检查视图中正在访问的属于“MenuCache”属性的任何实体,并使用 DataLoadOptions 预先加载它们。

标签: asp.net-mvc-3 datacontext


【解决方案1】:

我不能确定,但​​这可能与 return View(menu.ToList()) 有关,因为我相信实际结果(视图)直到稍后在 MVC 管道中才会执行,所以 ToList() 不是t 执行到您的 WebDataContext 被处置后。我敢打赌这会解决问题:

public ActionResult MainMenu(int id)
{
  IENumerable<MenuCache> menu;

  using (WebDataContext context = new WebDataContext())
  {
    menu = context.MenuCaches
                  .AsEnumerable()
                  .Where(x => x.ID == id 
                              && (x.Local == true || x.National == true));

    foreach (var item in menu)
    {
      if (item.Parent.Parent != null && item.Parent.ParentID == 0)
      {
        menu = item.Children;
      }
    }
    menu = menu.ToList();
  }
  return View(menu);
}

【讨论】:

  • 哇,所以这很可能是两件事之一;首先,您可能正试图从菜单访问另一个表中存在的关系对象,而您没有LoadWith() 那个对象,或者它是另一个WebDataContext 在其他地方。该错误实际上不应发生在控制器中,而应发生在视图中。实际的错误堆栈跟踪和代码位置是什么(使用此信息更新您的问题)?
【解决方案2】:

这就是我要做的,我会将WebDataContext 的范围设置为Controller 级别,override Dispose() 并在其中调用 context.Dispose()。

【讨论】:

    【解决方案3】:

    我很好奇您是否正在创建一个可枚举列表,以便稍后运行查询。 不知道您的“父母参考”是什么,很难说。但我 99.9% 确定这就是问题所在,您的 ToList 正在创建一个可以进一步查询的项目列表(并且在您的视图中)

    ViewModel 肯定会解决这个问题,但请确保您的视图没有访问任何尚未在列表中每个项目的根级别加载的属性(并且不会调用列表项中的任何子项目)

    【讨论】:

      【解决方案4】:

      将菜单传递到视图中实际上是进行浅拷贝(指针拷贝)。这将使连接保持活动状态。您需要执行菜单对象的深层复制。我敢打赌,如果您直接在数据上下文上调用 dispose,则视图将有一个空对象。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-12
        相关资源
        最近更新 更多