Ошибка «Доступ к DataContext после Dispose» при удалении текста данных из метода ActionResult в контроллере ASP.NET MVC 3 - PullRequest
0 голосов
/ 23 декабря 2011

Вот мой код:

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.Закомментированный код в функции был еще одним вариантом, который я нашел, но он тоже не работал.Есть идеи?Большое спасибо.

Ответы [ 4 ]

0 голосов
/ 13 февраля 2012

Передача меню в представление на самом деле принимает мелкую копию (указатель копирования). Это сохранит связь. Вам необходимо выполнить глубокую копию объекта меню. Могу поспорить, что если бы вы напрямую вызвали dispose для контекста данных, представление бы имело нулевой объект.

0 голосов
/ 23 декабря 2011

Не могу быть уверен, но, вероятно, это как-то связано с return View(menu.ToList()), так как я считаю, что фактический результат (представление) не выполняется до позднего времени в строке канала MVC, поэтому ToList() isn '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);
}
0 голосов
/ 24 декабря 2011

Мне любопытно, если вы создаете список перечислимых элементов, который затем может выполнять запросы позже.Не зная, каковы ваши родительские ссылки, трудно сказать.но я на 99,9% уверен, что в этом и заключается проблема, ваш ToList создает список элементов, которые могут быть запрошены (и по вашему мнению)не получает доступ к свойствам, еще не загруженным на корневом уровне каждого элемента в вашем списке (и не вызывает дочерние элементы в элементе списка)

0 голосов
/ 23 декабря 2011

Вот что я хотел бы сделать, я бы поместил WebDataContext на уровне Controller, override Dispose() и вызвал там context.Dispose ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...