在Html.DropDownListFor中,回发页面因DBContext错误而失败

时间:2014-10-21 18:06:36

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

我遇到了一个问题,在回发后,由于

,页面无法加载
  

由于已经处理了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 个答案:

答案 0 :(得分:2)

由于SelectListexpects 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()并不总是在数据库操作上如此轻松地使用,因为它有时会从数据库中撤回比实际需要更多的批次(通过实现记录在调用表达式树的其余部分之前),这会伤害性能。

答案 1 :(得分:2)

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

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

假设您要在控制器中直接使用上下文,“最佳实践”方法是在控制器上为您的上下文设置实例变量:

private readonly CharacterContext db = new CharacterContext();

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

db.Dispose();

Controller实现了IDisposable,并为每个请求进行了新的处理,因此您的上下文的生命周期也是按请求进行的。