2014-10-21 2 views
-1

Я бегу в проблему, где после постбэка, страница неисправного загрузить из-заПосле обратной передачи страницы с ошибкой DbContext в Html.DropDownListFor

Операция не может быть завершена, поскольку DbContext было расположены.

Я прошел через код и код .cs файл работает отлично, он бросает ошибку в .cshtml файле на

@Html.DropDownListFor(m => m.Section, Model.Sections, "--Select Section--", new { @id = "Section", disabled = "disabled" })<br /><br />

поэтому я немного запутался, как это происходит, поскольку файл .cshtml не вызывает контекст, а модель. Вот код бэкенд

using (CharacterContext db = new CharacterContext()) 
{ 
    model.Sections = new SelectList(db.Sections.OrderBy(s => s.Title), "ID", "Title"); 

    if (!FileHelper.IsImage(RaceImageFile)) 
    { 
     ModelState.AddModelError("Invalid File Type.", "Images must be JPG, GIF, or PNG files."); 
    } 

    if (ModelState.IsValid) 
    { 
     if (RaceImageFile != null) 
     { 
      string FolderName = GeneralHelper.GetSectionRoute(model.Section) + "/Races"; 
      model.RaceImageID = FileHelper.UploadSiteImage(FolderName, model.Name, RaceImageFile, model.RaceImageID.Value); 
     } 
     else 
     { 
      if (model.RaceImageID.HasValue) 
      { 
       FileHelper.UpdateFileName(model.Name, model.RaceImageID.Value); 
      } 
     } 

     Race UpdatedRace = new Race() 
     { 
      ID = model.ID, 
      Name = model.Name, 
      SectionID = model.Section, 
      RaceImageID = model.RaceImageID, 
      Description = model.Description 
     }; 

     db.Entry(UpdatedRace).State = EntityState.Modified; 
     db.SaveChanges(); 
     ViewBag.Results = "Race updated."; 
    } 

    return View(model); 
} 

ответ

2

С SelectList только expects an IEnumerable, я подозреваю, что это на самом деле не перечислении значения сразу, а ждет, пока это не оказывает мнение. И к тому времени, что происходит, контекст DB расположен так, что это не могут быть перечислены:

db.Sections.OrderBy(s => s.Title) 

В принципе, выполнение этого выражения откладывается до значения не перечислены, которые в данном случае слишком поздно.

Вы можете явно перечислить значения сразу материализуя выражение в список:

db.Sections.OrderBy(s => s.Title).ToList() 

Таким образом, вся линия будет:

model.Sections = new SelectList(db.Sections.OrderBy(s => s.Title).ToList(), "ID", "Title"); 

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

+0

Добавление '.ToList()' исправило проблему. – Matthew

2

Лучше всего избегать использования using с контекстами, так как он в значительной степени блокирует все функции ленивой загрузки Entity Framework. Есть причина, почему вы не видите using в любом из примеров ASP.NET MVC, касающихся базы данных.

Если вы его используете, то вам нужно быть очень осторожным, чтобы все данные, которые вы собираетесь использовать на странице, загружены до, которые вы возвращаете из своего действия. Это не плохо, само по себе, поскольку это заставляет вас осознавать вещи, которые могут быть ленивыми, без вашего ведома, но это настоящая боль, уверяю вас.

«Лучший практик» подход, при условии, что вы собираетесь работать непосредственно с контекстом в контроллере, чтобы установить переменный экземпляр на контроллере для вашего контекста:

private readonly CharacterContext db = new CharacterContext(); 

Тогда, в Dispose метод контроллера:

db.Dispose(); 

Controller реализует IDisposable, и и обновленный расположено для каждого запроса, поэтому срок службы вашего контекста является по запросу, а также.

Смежные вопросы