EF Core编辑实体未更新却新增的问题求助
问题分析与解决方案
你的问题核心是:编辑实体时EF Core执行了新增而非更新操作,根源是Post请求提交的Products对象主键ProductId未被正确赋值(默认值为0)。EF Core对int类型主键的默认规则是:值为0时判定为新实体,执行Add操作;只有主键值匹配数据库中已存在的记录时,才会执行Update操作。
解决方案1:确保视图提交主键值
编辑视图(Edit.cshtml)必须将ProductId作为隐藏字段包含在表单内,这样提交时主键才会被传递到后台:
@model Products <form asp-action="Edit"> <!-- 关键:添加隐藏字段传递主键 --> @Html.HiddenFor(model => model.ProductId) <div class="form-group"> <label asp-for="Name" class="control-label"></label> <input asp-for="Name" class="form-control" /> <span asp-validation-for="Name" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Price" class="control-label"></label> <input asp-for="Price" class="form-control" /> </div> <div class="form-group"> <label asp-for="Quantity" class="control-label"></label> <input asp-for="Quantity" class="form-control" /> </div> <div class="form-group"> <input type="submit" value="保存" class="btn btn-primary" /> </div> </form>
解决方案2:更安全的控制器更新逻辑
直接使用Update方法依赖EF的状态追踪,若实体脱离上下文容易出现误判。更稳妥的方式是先从数据库获取原实体,再映射提交的字段值:
[HttpPost] [ValidateAntiForgeryToken] public IActionResult Edit(Products obj) { if (ModelState.IsValid) { // 从数据库获取被上下文追踪的原实体 var productFromDb = _db.Products.Find(obj.ProductId); if (productFromDb == null) { return NotFound(); } // 手动更新需要修改的字段 productFromDb.Name = obj.Name; productFromDb.Price = obj.Price; productFromDb.Quantity = obj.Quantity; // 无需调用Update,上下文会自动追踪实体变化 _db.SaveChanges(); return RedirectToAction("Products"); } return View(obj); }
调试检查点
可以在Post方法开头添加调试代码,确认主键是否正确传递:
// 在ModelState.IsValid判断前添加 Console.WriteLine($"提交的ProductId:{obj.ProductId}");
如果输出为0,说明视图未提交主键,回到解决方案1检查表单代码。
内容的提问来源于stack exchange,提问作者ruslana
相关产品推荐
相关产品推荐

