I am building a habit tracking application in Blazor with an ASP.NET Core 6 Web API for backend which uses Entity Framework. I have a Habit entity which owns many Implementation entities like this:
modelBuilder.Entity<Habit>().OwnsMany(h => h.Implementations);
I am trying to add an implementation to a habit which already has an existing implementation. This is the code within my controller action method:
public async Task<IActionResult> AddHabitReview([FromBody] HabitReviewModel model)
{
try
{
var habit = await _context.Habits.FindAsync(model.Id);
if (habit == null)
return NotFound("No habit found");
habit.AddImplementation(/*implementation parameters*/);
_context.Habits.Update(habit);
await _context.SaveChangesAsync();
return Ok();
}
catch (Exception ex)
{
var message = ex.Message;
return BadRequest(message);
}
}
but I am getting the following exception:
The database operation was expected to affect 1 row(s), but actually affected 0 row(s); data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions.
I also checked the DB query via SQL Server profiler. For some reason, it is creating an UPDATE command for Implementation table with Id as my new implementation ID. I expected it to generate a CREATE command for Implementation table, since I was creating a new implementation and attaching it to the habit entity.
Can someone point out what I am doing wrong?
The root of the error is that EF Core tried to update the Habit entity, but did not properly handle the changes to the Implementation collection.
So the correct usage like below: