使用EF 5.0在MVC中删除记录时触发DbUpdateException问题求助
解决EF 5.0 MVC删除数据时
SaveChanges()抛出异常的问题 咱们先拆解你代码里可能触发异常的几个关键点,不用try-catch也能提前规避这些问题:
1. 先处理Find(id)返回null的情况
你的代码直接用db.FoodItems.Find(id)获取实体,但如果数据库里没有对应ID的记录,food会是null,这时候调用Remove(food)必然触发异常。可以先加个存在性判断:
[HttpPost, ActionName("Delete")] public ActionResult DeleteConfirmed(int id) { using (OrderDBContext db = new OrderDBContext()) { FoodItem food = db.FoodItems.Find(id); if (food != null) { // 先确认实体存在再执行删除 db.FoodItems.Remove(food); db.SaveChanges(); } } return RedirectToAction("Index"); }
2. 排查外键约束导致的异常
这是删除操作里最常见的问题:如果FoodItem表和其他表(比如OrderDetail这类关联表)有外键绑定,且关联的子记录还存在,数据库会因为参照完整性约束阻止你删除这条FoodItem。
解决思路分两种:
- 如果你希望删除
FoodItem时自动删除关联的子记录,可以在EF的实体配置里开启级联删除:// 在你的OrderDBContext的OnModelCreating方法中添加配置 protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<OrderDetail>() .HasRequired(od => od.FoodItem) .WithMany(f => f.OrderDetails) .WillCascadeOnDelete(true); } - 如果不允许级联删除,那你需要先手动清理所有关联的子记录,再删除
FoodItem。
3. 规避并发冲突问题
如果在你查询到FoodItem到执行删除的间隙,这条记录被其他请求修改或删除了,会触发并发异常。你可以用更直接的删除方式,绕过实体追踪步骤:
// 不用先查询实体,直接构造带ID的实体标记为删除状态 [HttpPost, ActionName("Delete")] public ActionResult DeleteConfirmed(int id) { using (OrderDBContext db = new OrderDBContext()) { var food = new FoodItem { Id = id }; db.Entry(food).State = EntityState.Deleted; db.SaveChanges(); } return RedirectToAction("Index"); }
这种方式更高效,也能避免查询后实体被修改的并发问题,但同样要注意外键约束的限制。
4. 检查数据库权限
如果你的应用程序使用的数据库账号没有FoodItems表的删除权限,也会在SaveChanges()时抛出权限异常,记得确认下账号的权限设置。
内容的提问来源于stack exchange,提问作者Rhushikesh
相关产品推荐
相关产品推荐

