Sto ottenendo l'entità modificata da fronted, mappandola sul lato backend e semplicemente voglio aggiornarla nel database. L'aggiornamento si sta comportando così:
[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();
}}
Prima di questa azione, sto ricevendo l'elenco degli utenti e inviandolo al frontend. Anche se ho impostato QueryTrackingBehavior su NoTracking, sto ricevendo un'eccezione:
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.'
Dove Contract è un'entità correlata per Worker che viene aggiornata ...
Qualche idea su cosa sto facendo male qui?
AGGIORNARE:
Lavoratore - Rapporto contrattuale:
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; }
}
Va bene! ha il problema nel tuo codice Non hai mappato l'entità aggiornata all'entità esistente che hai estratto dal database. Devi mappare l'entità aggiornata all'entità esistente. Per fare ciò è possibile utilizzare AutoMapper
o mapping esplicito come segue:
Puoi risolvere il problema come segue:
[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();
}
}
In alternativa puoi provare come segue:
[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();
}
}