EF Core 2.0 update - tracking issue

asp.net-core ef-core-2.0 entity-framework-core postgresql

Question

I am getting changed entity from fronted, mapping it on backend side and simply want to update it in database. Update is performing like this:

[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();
        }}

Before this action, i am getting the list of users and sending it to frontend. Although I set QueryTrackingBehavior to NoTracking, i am getting exception:

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.'

Where Contract is related entity for Worker which is updated...

Any idea what i am doing wrong here?

UPDATE:

Worker - Contract relation:

   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; }
}
1
2
7/17/2018 8:47:24 AM

Popular Answer

Okay! got the problem in your code. You didn't map the updated entity to the existing entity that you pulled from the database. You have to map the updated entity to the existing entity. To do so you can use AutoMapper or explicit mapping as follows:

You can solve the problem as follows:

[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();
        }
 }

Alternatively you can try as follows:

[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();
      }
}
1
7/17/2018 9:15:26 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow