You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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配置

  1. 删除末尾的冗余主键配置行:modelBuilder.Entity<Product>().HasKey(bc => bc.GameId );
  2. 统一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");
}
  1. 删掉末尾重复声明的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 13:54:03