ASP.NET API报错:Pizza实体实例无法被跟踪,存在重复键值
报错原文及翻译
原始报错:
The instance of entity type 'Pizza' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.
翻译:
实体类型Pizza的实例无法被跟踪,因为另一个拥有相同Id键值的实例已经处于被跟踪状态。附加现有实体时,请保证每个主键值对应的实体实例唯一。可以通过DbContextOptionsBuilder.EnableSensitiveDataLogging查看具体冲突的键值。
涉及代码
DeliveryCollectionModel 定义
public class DeliveryCollectionModel { public Delivery? Delivery { get; set; } public List<Pizza>? Pizza { get; set; } }
API 接口代码
[HttpPost] [Route("add/w/Pizza")] public async Task<ActionResult<DeliveryCollectionModel>> AddDeliveryWithPizza(DeliveryCollectionModel model) { _dataContext.Delivery.Add(model.Delivery); await _dataContext.SaveChangesAsync(); string id = model.Delivery.Id.ToString(); // Delivery的Id是自增整数 foreach (var currentPizza in model.Pizza) // Pizza的Id是字符串类型,非自增 { currentPizza.Id = "G" + id; _dataContext.Pizza.Add(currentPizza); } await _dataContext.SaveChangesAsync(); return Ok("G" + id); }
根本原因
你在循环里给所有要添加的Pizza实体设置了完全相同的Id值:"G" + id,这里的id是新增Delivery的唯一Id,导致所有Pizza的主键都重复了。
而Entity Framework Core的上下文(_dataContext)会跟踪所有它管理的实体,不允许同一个上下文里存在两个主键相同的同类型实体。当你添加第一个Pizza后,上下文已经开始跟踪这个Id的实体,后续再添加同Id的Pizza时,就会触发这个跟踪冲突的报错。
内容的提问来源于stack exchange,提问作者Maubi

