使用EntityState.Deleted删除记录时误删同Id全部记录的问题
解决EF删除时误删同主键多条记录的问题
你遇到的问题核心是Entity Framework仅根据主键识别要删除的记录:
- 你的模型中
Id是唯一主键,EF在处理context.Entry(favDetails).State = EntityState.Deleted时,只会读取Id字段作为匹配条件,完全忽略FavId。所以即使你设置了FavId,EF也会删除所有Id等于给定值的记录,而不是Id+FavId组合匹配的那条。
解决方案1:直接删除查询到的目标对象
既然你已经通过查询获取到了正确的Dtl记录,直接用EF的Remove方法删除这个跟踪对象即可,EF会精准定位这条记录:
using (var context = new DataContext()) { var query = from st in context.Favourites where st.Id == id && st.FavId == fav_id select st; var Dtl = query.FirstOrDefault<FavouritesModel>(); if (Dtl != null) { // 直接删除查询到的对象 context.Favourites.Remove(Dtl); } // 新增逻辑(如果需要) // else // { // context.Favourites.Add(new FavouritesModel { Id = id, FavId = fav_id, Name = "你的名称" }); // } context.SaveChanges(); }
解决方案2:设置复合主键(根本解决业务匹配问题)
从业务逻辑看,Id和FavId组合才是唯一标识,所以应该将它们设置为复合主键。这样EF会同时根据两个字段定位记录,你原来的删除方式也能正常工作。
方式A:使用数据注解
修改模型类:
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; public partial class FavouritesModel { [Key] [Column(Order = 0)] public string Id { get; set; } = null!; [Key] [Column(Order = 1)] public string FavId { get; set; } = null!; public string Name { get; set; } = null!; }
方式B:使用Fluent API(推荐,分离配置和模型)
在你的DataContext中重写OnModelCreating方法:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<FavouritesModel>() .HasKey(f => new { f.Id, f.FavId }); }
解决方案3:直接执行删除SQL(高效无跟踪)
如果不想加载对象到内存,可以使用EF Core的ExecuteDelete方法(EF Core 3.0及以上支持),直接生成并执行删除语句,只删除符合条件的记录:
using (var context = new DataContext()) { // 直接删除匹配条件的记录 var deletedCount = context.Favourites .Where(f => f.Id == id && f.FavId == fav_id) .ExecuteDelete(); // 没有删除到记录则新增 if (deletedCount == 0) { context.Favourites.Add(new FavouritesModel { Id = id, FavId = fav_id, Name = "你的名称" }); } context.SaveChanges(); }
内容的提问来源于stack exchange,提问作者user616076
相关产品推荐
相关产品推荐

