回发页面失败后,Html.DropDownListFor处出现DBContext错误

本文关键字:DropDownListFor 错误 DBContext Html 失败 | 更新日期: 2023-09-27 18:27:17

我遇到了一个问题,回发后,页面由于而无法加载

操作无法完成,因为DbContext已被释放。

我已经逐步完成了代码,.cs文件代码运行良好,它在上的.cs.html文件中抛出了错误

@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);
}

回发页面失败后,Html.DropDownListFor处出现DBContext错误

由于SelectList只需要一个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()在数据库操作中的使用并不总是那么简单,因为它有时会从数据库中提取比实际需要更多的(通过在调用表达式树的其余部分之前具体化记录),这会影响性能。

最好避免在上下文中使用using,因为它几乎会破坏实体框架的所有延迟加载功能。在任何处理数据库的ASP.NET MVC示例中都看不到using,这是有原因的。

如果您确实使用了它,那么您必须非常小心,在您从操作返回之前,您打算在页面上使用的所有数据都会被急切地加载。这本身并不是一件坏事,因为它让你意识到,在你不知情的情况下,可能会有一些懒惰的事情,但我向你保证,这是一种真正的痛苦。

"最佳实践"方法,假设您将直接在控制器中处理上下文,是在控制器上为上下文设置一个实例变量:

private readonly CharacterContext db = new CharacterContext();

然后,在控制器的Dispose方法中:

db.Dispose();

Controller实现了IDisposable,并为每个请求创建和处理,因此上下文的生存期也是每个请求的。