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

EF Core 2.0.1多对多关联插入报错:实体跟踪重复键问题

解决EF Core 2.0.1多对多关联插入的跟踪冲突问题

这个错误的核心原因是你手动创建的ReferenciaFabricanteTieneReferenciaConstructor实例都带着IdReferenciaFabricante=0和IdReferenciaConstructor=0的复合键——EF Core的跟踪机制会把这些键值完全相同的实例当成同一个实体,所以循环添加时就触发了"重复跟踪"的错误。而且EF Core 2.x不会自动帮你把新插入主实体(ReferenciaFabricante/ReferenciaConstructor)生成的ID同步到连接实体的外键上,除非你正确建立导航属性关联,或者先保存主实体拿到ID。

下面给出两种常用场景的解决方案:

场景1:同时插入新的主实体并建立关联

这种情况不需要手动将连接实体添加到DbSet,只需要通过导航属性关联,EF会自动处理插入和外键赋值:

// 创建新的制造商实例
var nuevaFabricante = new ReferenciaFabricante
{
    // 填充其他属性
    ReferenciaFabricanteTieneReferenciaConstructor = new List<ReferenciaFabricanteTieneReferenciaConstructor>()
};

// 创建新的构造商实例
var nuevaConstructor = new ReferenciaConstructor
{
    // 填充其他属性
    ReferenciaFabricanteTieneReferenciaConstructor = new List<ReferenciaFabricanteTieneReferenciaConstructor>()
};

// 创建连接实体并关联两个主实体
var conexion = new ReferenciaFabricanteTieneReferenciaConstructor
{
    ReferenciaFabricante = nuevaFabricante,
    ReferenciaConstructor = nuevaConstructor
};

// 将连接实体添加到任意一个主实体的导航属性中
nuevaFabricante.ReferenciaFabricanteTieneReferenciaConstructor.Add(conexion);

// 只需添加主实体到上下文,EF会自动插入连接实体
_dbContext.ReferenciaFabricante.Add(nuevaFabricante);
_dbContext.SaveChanges();

场景2:其中一个主实体已存在,另一个是新插入

如果其中一方已经在数据库中,先确保该实体被EF跟踪,再创建连接实体:

// 获取已存在的构造商(或通过Attach方法附加到上下文)
var constructorExistente = _dbContext.ReferenciaConstructor.Find(idConstructor);

// 创建新的制造商实例
var nuevaFabricante = new ReferenciaFabricante
{
    // 填充其他属性
    ReferenciaFabricanteTieneReferenciaConstructor = new List<ReferenciaFabricanteTieneReferenciaConstructor>()
};

// 创建连接实体,关联已存在的构造商和新制造商
var conexion = new ReferenciaFabricanteTieneReferenciaConstructor
{
    ReferenciaConstructor = constructorExistente,
    ReferenciaFabricante = nuevaFabricante
};

nuevaFabricante.ReferenciaFabricanteTieneReferenciaConstructor.Add(conexion);

_dbContext.ReferenciaFabricante.Add(nuevaFabricante);
_dbContext.SaveChanges();

原代码出错的关键原因

  1. 所有连接实体的复合键都是(0,0),EF认为它们是同一个实体,导致跟踪冲突;
  2. 你没有将连接实体与对应的主实体通过导航属性关联,EF无法自动将主实体插入后生成的ID赋值给连接实体的外键。

额外注意事项

  1. 你的模型配置是正确的,无需修改:
modelBuilder.Entity<ReferenciaFabricanteTieneReferenciaConstructor>()
    .HasKey(v => new { v.IdReferenciaFabricante, v.IdReferenciaConstructor });
  1. 如果一定要手动添加连接实体到DbSet,必须先保存主实体拿到生成的ID,再赋值给连接实体的外键:
// 先保存主实体,获取自动生成的ID
_dbContext.ReferenciaFabricante.Add(nuevaFabricante);
_dbContext.ReferenciaConstructor.Add(nuevaConstructor);
_dbContext.SaveChanges();

// 用生成的ID创建连接实体
var conexion = new ReferenciaFabricanteTieneReferenciaConstructor
{
    IdReferenciaFabricante = nuevaFabricante.Id,
    IdReferenciaConstructor = nuevaConstructor.Id
};

_dbContext.ReferenciaFabricanteTieneReferenciaConstructor.Add(conexion);
_dbContext.SaveChanges();

内容的提问来源于stack exchange,提问作者SySc0d3r

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:14:52