0

I have a web API which has a scaffold-ed ApiController. In update method (PUT) following code segment updates the entity in the database.

_context.Entry(customers).State = EntityState.Modified;

try
{
    await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
    if (!CustomersExists(id))
    {
        return NotFound("Not found");
    }
    else
    {
        throw;
    }
}

But I found out that this only updates the attributes in Customer model only, It does not propagate to referenced entities. As an example, There are Orders table which stores orders of each customer.

public partial class Customers
{
    public Customers()
    {
        Orders= new HashSet<Orders>();
    }

    public string Description { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Orders> Orders { get; set; }
}

So the request to update a customer can have updated order details as well. But,

_context.Entry(customers).State = EntityState.Modified; 

this line fails to update Orders table if there is a change. After trying out many methods, I found out that,

_context.Customers.Update(customers);

manages to update everything successfully. But problem with that is if the current request has only 2 Orders and the update request has additional order(3 orders), again the update fails.

Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded.

Edit: There are no any connections to the database. So concurrency exception is impossible.

My JSON request looks like this.

{
   "orders":[
      {
         "id": "1",
         "date": "2018/10/29"
      },
      {
      },
   ],
   "name":"test_name",
   "description":"test_description",
}

Any help will be highly appreciated. Thank you.

Nishan
  • 3,644
  • 1
  • 32
  • 41
  • https://stackoverflow.com/a/32558609/2946329 – Salah Akbari Oct 29 '18 at 08:46
  • This is a *data access error*. It has nothing to do with ASP.NET or scaffolding. This error means that the record was modified by someone else (another request?) since it was retrieved. You'll have to decide what to do, retry the operation, reload the record, or throw and warn the user that something weird happened? – Panagiotis Kanavos Oct 29 '18 at 08:47
  • Check [Handling Concurrency Conflicts](https://learn.microsoft.com/en-us/ef/core/saving/concurrency) in the EF Core documentation. It explains how optimistic concurrency works and how to check what was changed in case of a conflict – Panagiotis Kanavos Oct 29 '18 at 08:55
  • I'm pretty sure that I am the only person who is using the database. This occurs when I send a `POST` request, get the data, then trying to update the the data set with additional `order`. In between no one access the database. – Nishan Oct 29 '18 at 09:06
  • See, you changed the data. Why don't you check all your orders, after submitting the customer entity. Update or Insert each order and after this is done, update the customr. Wrap it all in a transaction scope. – Marco Mar 08 '19 at 21:20

2 Answers2

0

I had the same problem. I'm using EF Core 2 on a new project. Post edit action method was generating a DbUpdateConcurrencyException on any update.

_context.Update(participant);
await _context.SaveChangesAsync();

I had to replace the two lines above with this:

var participantToUpdate = await _context.Participants.SingleOrDefaultAsync(p => p.ParticipantID == participant.ParticipantID);
if (await TryUpdateModelAsync<Participant>(participantToUpdate, "", p => p.Nom, p => p.Email))
{
    await _context.SaveChangesAsync();
}
jtate
  • 2,612
  • 7
  • 25
  • 35
0

you can add near all props [ConcurrencyCheck]

[ConcurrencyCheck] public string Name{ get; set; }