我正在从前端改变实体,将其映射到后端,只是想在数据库中更新它。 更新的执行情况如下:
[HttpPut("{id}")]
public IActionResult Update(string id, [FromBody]Worker worker)
{
using (var dbContext= new MyDbContext())
{
dbContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
var entity = dbContext.Workers.FirstOrDefault(r => r.Id == worker.Id);
if (entity == null) return BadRequest();
dbContext.Workers.Update(worker);
dbContext.SaveChanges();
return Ok();
}}
在执行此操作之前,我正在获取用户列表并将其发送到前端。 尽管我将QueryTrackingBehavior设置为NoTracking,但是却出现异常:
System.InvalidOperationException: 'The instance of entity type 'Contract' cannot be tracked because another instance with the key value 'Id:4' is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.'
合同是与工人相关的实体,已更新...
知道我在做什么错吗?
更新:
工人-合同关系:
public class Worker: IId
{
public int Id { get; set; }
public ICollection<Contract> Contracts{ get; set; }
}
public class Contract: IId
{
public int Id { get; set; }
public int WorkerId { get; set; }
public Worker Worker { get; set; }
}
答案 0 :(得分:1)
好吧!在您的代码中遇到了问题。您没有将更新后的实体映射到从数据库中拉出的现有实体。您必须将更新的实体映射到现有实体。为此,您可以使用AutoMapper
或显式映射,如下所示:
您可以解决以下问题:
[HttpPut("{id}")]
public IActionResult Update(string id, [FromBody]Worker worker)
{
using (var dbContext= new MyDbContext())
{
var entityToBeUpdated = dbContext.Workers.AsNoTracking().FirstOrDefault(r => r.Id == worker.Id);
if (entity == null) return BadRequest();
entityToBeUpdated.Property1 = worker.Property1;
entityToBeUpdated.Property2 = worker.Property2;
// Do the same for the other changed properties as well
dbContext.Workers.Update(entityToBeUpdated);
dbContext.SaveChanges();
return Ok();
}
}
或者,您也可以尝试以下操作:
[HttpPut("{id}")]
public IActionResult Update(string id, [FromBody]Worker worker)
{
using (var dbContext= new MyDbContext())
{
var entityToBeUpdated = dbContext.Workers.FirstOrDefault(r => r.Id == worker.Id);
if (entity == null) return BadRequest();
entityToBeUpdated.Property1 = worker.Property1;
entityToBeUpdated.Property2 = worker.Property2;
// Do the same for the other changed properties as well.
dbContext.SaveChanges();
return Ok();
}
}