Entity Framework Database First多对多关系下生成错误删除查询问题
问题根因
你的问题由三处核心错误导致:
- 主键配置被覆盖:你在所有
UsingEntity<Product>配置中都声明了Product的复合主键,但代码末尾单独加了一行modelBuilder.Entity<Product>().HasKey(bc => bc.GameId );,这行代码直接覆盖了之前的复合主键配置,让EF Core认为GameId是Product的唯一主键,所以删除时只会按GameId匹配记录。 - 复合主键配置不一致:在Game和Manufacture的多对多配置的
UsingEntity块中,你声明的复合主键少了LocalizationId字段,和其他关联的复合主键规则不统一,会引发主键匹配异常。 - 删除操作参数不全:就算主键配置正确,你构造删除的Product对象时只赋值了
GameId和GenreId,没有给出复合主键要求的其他字段值,EF Core也无法准确定位到要删除的单条记录。
修复步骤
第一步:修正Fluent API配置
- 删除末尾的冗余主键配置行:
modelBuilder.Entity<Product>().HasKey(bc => bc.GameId ); - 统一Game和Manufacture多对多配置中的复合主键,补全
LocalizationId,和其他关联的主键规则保持一致:
// 修正Manufacture关联的UsingEntity块中的主键配置 j => { j.HasKey(t => new { t.GameId, t.ManufactureId, t.GenreId, t.PlatformId, t.RegionrestrictId, t.LocalizationId }); j.ToTable("Products"); }
- 删掉末尾重复声明的Product和各实体的外键配置,这些规则在
UsingEntity中已经声明过,冗余配置容易引发冲突。
第二步:修正删除操作逻辑
优先使用先查询再删除的方案,不需要手动补全所有主键字段,稳定性更高:
var productToDelete = _context.Products.FirstOrDefault(p => p.GameId == 1 && p.GenreId == 1); if (productToDelete != null) { _context.Products.Remove(productToDelete); _context.SaveChanges(); }
如果要使用存根对象提升删除性能,需要补全复合主键的所有字段值:
var productStub = new Product() { GameId = 1, GenreId = 1, // 补全其他主键字段的对应值 PlatformId = xxx, ManufactureId = xxx, LocalizationId = xxx, RegionrestrictId = xxx }; _context.Entry(productStub).State = EntityState.Deleted; _context.SaveChanges();
内容的提问来源于stack exchange,提问作者mistake22
相关产品推荐
相关产品推荐

