ASP.NET Core编辑Staff记录时未更新原数据反而新增记录的问题求助
ASP.NET Core编辑Staff记录时未更新原数据反而新增记录的问题求助
看起来你遇到的问题是EF Core把编辑操作当成了新增操作,核心原因确实是**StaffId没有被正确传递到POST控制器方法**,导致EF无法识别出要更新的现有实体,最终执行了插入逻辑。下面我们一步步分析并解决这个问题:
问题根源解析
EF Core的db.Staff.Update(staff)方法有个关键行为:如果传入实体的主键(这里是StaffId)是默认值(int类型默认是0),或者该实体没有被当前上下文追踪,EF会将其视为新实体,执行INSERT操作而非UPDATE。你的表单里没有提交StaffId,所以POST过来的Staff对象的StaffId是0,EF自然就新增了一条记录。
解决方案一:添加隐藏字段传递StaffId(快速修复)
这是最直接的修复方式,只需要在你的EditUser.cshtml表单里添加一个绑定StaffId的隐藏字段,提交表单时StaffId就会被一起发送到控制器:
<form asp-action="EditUser" asp-controller="Admin" asp-route-id="@Model.StaffId"> <!-- 新增隐藏字段,自动填充Model中的StaffId值 --> <input type="hidden" asp-for="StaffId" /> <!-- 原有表单内容保持不变 --> <div class="form-group"> <label asp-for="Login" class="control-label">Логин</label> <input type="text" asp-for="Login" class="form-control" /> </div> <div class="form-group"> <label asp-for="Pass" class="control-label">Пароль</label> <input type="text" asp-for="Pass" class="form-control" /> </div> <div class="form-group"> <label asp-for="RoleId" class="control-label">Роль</label> <select asp-for="RoleId" asp-items="ViewBag.roli" class="form-control"></select> </div> <div class="form-group"> <button type="submit" class="btn btn-primary btn-sm">Изменить</button> </div> </form>
因为视图是强类型绑定到Staff模型,asp-for="StaffId"会自动填充Model里的StaffId值,提交后POST方法就能收到正确的ID,此时db.Staff.Update(staff)就会识别到是现有实体,执行UPDATE操作。
解决方案二:使用「获取-更新-保存」模式(更安全)
这种方式可以避免过度提交风险(比如用户恶意修改不该改的字段),同时也能确保我们操作的是数据库中存在的实体,推荐在生产环境使用:
[HttpPost] public IActionResult EditUser(Staff submittedStaff) { // 先从数据库获取要更新的实体 var existingStaff = db.Staff.FirstOrDefault(x => x.StaffId == submittedStaff.StaffId); if (existingStaff == null) { // 处理找不到用户的情况 return NotFound("该用户不存在"); } // 手动将提交的属性值映射到现有实体 existingStaff.Login = submittedStaff.Login; existingStaff.Pass = submittedStaff.Pass; existingStaff.RoleId = submittedStaff.RoleId; // 保存更改,EF会追踪到现有实体的变化,自动执行UPDATE db.SaveChanges(); return RedirectToAction("UserList"); }
这种方式不需要依赖Update方法,而是直接更新被EF上下文追踪的现有实体,安全性更高,也能彻底避免主键未传递导致的新增问题。
额外优化建议
在GET方法里补充参数合法性校验,能处理一些非法请求的情况:
[HttpGet] public IActionResult EditUser(int? id) { if (id == null) { return BadRequest("缺少用户ID"); } Staff user = db.Staff.FirstOrDefault(x => x.StaffId == id); if (user == null) { return NotFound("该用户不存在"); } ViewBag.roli = new SelectList(db.Rols.ToList(), "RoleId", "RoleName"); return View(user); }
内容来源于stack exchange
相关产品推荐
相关产品推荐

