.NET Core中为模型创建控制器后遭遇实体上下文问题
排查Event控制器相关问题
看起来你在为Event模型搭建控制器后遇到了问题,我先帮你梳理下现有代码,并给出一些常见问题的排查方向——虽然你没明确说明具体的报错或异常现象,但从代码里能看到几个潜在的问题点:
1. 核心模型代码
Event模型
public class Event { public int ID { get; set; } [Required] public string Title { get; set; } [Required] public string Description { get; set; } [DataType(DataType.Date)] [Required] public DateTime Date { get; set; } public Subcategory Subcategory { get; set; } public int SubcategoryID { get; set; } public Place Place { get; set; } public int PlaceID { get; set; } public Organisator Organisator { get; set; } public int OrganisatorID { get; set; } public ICollection<User_link> User_link { get; set; } }
Place模型(一对多关联示例)
Subcategory、Place、Organisator均与Event为一对多关联,这里以Place为例:
public class Place { public int ID { get; set; } [Required] public string Title { get; set; } [Required] public string Address { get; set; } [Required] public string Call_number { get; set; } public string Email { get; set; } public string Vk { get; set; } public string Facebook { get; set; } public ICollection<Event> Event { get; set; } }
2. EventsController代码
public class EventsController : Controller { private readonly ApplicationDbContext _context; public EventsController(ApplicationDbContext context) { _context = context; } // GET: Events public async Task<IActionResult> Index() { var applicationDbContext = _context.Event.Include(@ => @.Organisator).Include(@ => @.Place).Include(@ => @.Subcategory); return View(await applicationDbContext.ToListAsync()); } // GET: Events/Details/5 public async Task<IActionResult> Details(int? id) { if (id == null) { return NotFound(); } var @event = await _context.Event .Include(@ => @.Organisator) .Include(@ => @.Place) .Include(@ => @.Subcategory) .SingleOrDefaultAsync(m => m.ID == id); if (@event == null) { return NotFound(); } return View(@event); } // GET: Events/Create public IActionResult Create() { ViewData["OrganisatorID"] = new SelectList(_context.Organisator, "ID", "Title"); ViewData["PlaceID"] = new SelectList(_context.Place, "ID", "Address"); ViewData["SubcategoryID"] = new SelectList(_context.Subcategory, "ID", "Title"); return View(); } // POST: Events/Create // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see http://go.microsoft.com/fwlink/?LinkId=317598. [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create([Bind("ID,Title,Description,Date,SubcategoryID,PlaceID,OrganisatorID")] Event @event) { if (ModelState.IsValid) { _context.Add(@event); await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } ViewData["OrganisatorID"] = new SelectList(_context.Organisator, "ID", "Title", @event.OrganisatorID); ViewData["PlaceID"] = new SelectList(_context.Place, "ID", "Address", @event.PlaceID); ViewData["SubcategoryID"] = new SelectList(_context.Subcategory, "ID", "Title", @event.SubcategoryID); return View(@event); } // GET: Events/Edit/5 public async Task<IActionResult> Edit(int? id) { if (id == null) { return NotFound(); } var @event = await _context.Event.SingleOrDefaultAsync(m => m.ID == id); if (@event == null) { return NotFound(); } ViewData["OrganisatorID"] = new SelectList(_context.Organisator, "ID", "Title", @event.OrganisatorID); ViewData["PlaceID"] = new SelectList(_context.Place, "ID", "Address", @event.PlaceID); ViewData["SubcategoryID"] = new SelectList(_context.Subcategory, "ID", "Title", @event.SubcategoryID); return View(@event); } // POST: Events/Edit/5 // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see http://go.microsoft.com/fwlink/?LinkId=317598. [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Edit(int id, [Bind("ID,Title,Description,Date,SubcategoryID,PlaceID,OrganisatorID")] Event @event) { if (id != @event.ID) { return NotFound(); } if (ModelState.IsValid) { try { _context.Update(@event); await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!EventExists(@event.ID)) { return NotFound(); } else { throw; } } return RedirectToAction(nameof(Index)); } ViewData["OrganisatorID"] = new SelectList(_context.Organisator, "ID", "Title", @event.OrganisatorID); ViewData["PlaceID"] = new SelectList(_context.Place, "ID", "Address", @event.PlaceID); ViewData["SubcategoryID"] = new SelectList(_context.Subcategory, "ID", "Title", @event.SubcategoryID); return View(@event); } // GET: Events/Delete/5 public async Task<IActionResult> Delete(int? id) { if (id == null) { return NotFound(); } var @event = await _context.Event .Include(@ => @.Organisator) .Include(@ => @.Place) .Include(@ => @.Subcategory) .SingleOrDefaultAsync(m => m.ID == id); if (@event == null) { return NotFound(); } return View(@event); } // POST: Event }
3. 重点排查与修复建议
(1)控制器代码不完整
你的Delete动作的POST方法只写了注释就中断了,这会导致删除功能完全无法使用,补全代码如下:
[HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public async Task<IActionResult> DeleteConfirmed(int id) { var @event = await _context.Event.FindAsync(id); if (@event == null) { return NotFound(); } _context.Event.Remove(@event); await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } // 补全缺失的EventExists方法 private bool EventExists(int id) { return _context.Event.Any(e => e.ID == id); }
(2)模型命名冲突风险
Event是C#的关键字,虽然你用@event来规避编译错误,但长期来看容易引发混淆,建议把模型重命名为EventItem或者EventEntity这类更清晰的名称。
(3)关联数据加载遗漏
在Edit的GET方法中,你没有加载Organisator、Place、Subcategory这些关联实体,如果视图需要显示这些关联数据(比如编辑页面要显示场地名称),会直接抛出空引用异常,修改代码如下:
var @event = await _context.Event .Include(e => e.Organisator) .Include(e => e.Place) .Include(e => e.Subcategory) .SingleOrDefaultAsync(m => m.ID == id);
(4)下拉列表显示字段不合理
在Create和Edit中,Place的下拉列表用了Address作为显示文本,用户选择时可能更希望看到场地的Title,可以根据需求调整:
ViewData["PlaceID"] = new SelectList(_context.Place, "ID", "Title", @event.PlaceID);
(5)ModelState验证排查
如果创建/编辑时出现页面回退但没有提示,建议在视图中添加验证摘要,方便查看具体的验证失败原因:
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
如果这些建议没解决你的问题,欢迎补充具体的报错信息、异常现象或者功能失效的场景,我再帮你深入排查!
内容的提问来源于stack exchange,提问作者uldrsk
相关产品推荐
相关产品推荐

