EF Core中如何删除复合主键关联表的记录?
EF Core复合主键删除的正确实现
首先,你遇到的错误是因为Remove方法需要接收实体类的实例或者对应的EntityEntry对象,而不是匿名类型。EF Core无法识别你传入的匿名对象,所以报错。
另外先修正一个配置错误:你的OnModelCreating中HasKey(x => new { x.ParentId, x.ChildSettingId })写错了,实体类TmpExample的属性是ChildId,不是ChildSettingId,这个必须修正,否则主键映射会失效。
下面是几种正确的复合主键删除方式:
方式1:构造实体实例直接删除(无需查询数据库)
直接创建TmpExample实例并设置主键值,用Remove方法标记删除,EF Core会自动处理上下文附加,这种方式不会查询数据库,性能较高:
public async Task DeleteAsync(int parentId, int childId, CancellationToken ct = default) { var entity = new TmpExample { ParentId = parentId, ChildId = childId }; _context.StackQuestion.Remove(entity); await _context.SaveChangesAsync(ct); }
方式2:先查询实体再删除(适合需要验证存在性的场景)
如果需要先确认记录存在再执行删除,可以用FindAsync方法(优先查询上下文缓存,无缓存时再查数据库):
public async Task DeleteAsync(int parentId, int childId, CancellationToken ct = default) { var entity = await _context.StackQuestion.FindAsync(new object[] { parentId, childId }, ct); if (entity != null) { _context.StackQuestion.Remove(entity); await _context.SaveChangesAsync(ct); } }
方式3:批量删除(EF Core 3.0+支持,性能最优)
如果不需要将实体加载到内存,直接生成SQL删除语句执行,推荐用ExecuteDeleteAsync:
public async Task DeleteAsync(int parentId, int childId, CancellationToken ct = default) { await _context.StackQuestion .Where(e => e.ParentId == parentId && e.ChildId == childId) .ExecuteDeleteAsync(ct); }
内容的提问来源于stack exchange,提问作者Travis
相关产品推荐
相关产品推荐

