回发页面失败后,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);
}
由于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
,并为每个请求创建和处理,因此上下文的生存期也是每个请求的。