When we create a single generic repository for all the entities in our DbContext, then when we update any entity we have to set its state to modified, otherwise it will not be updated and the Entity Framework will throw an exception like below:
Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.GetOrCreateEntry(Object entity)\r\n
at Microsoft.EntityFrameworkCore.DbContext.EntryWithoutDetectChanges[TEntity](TEntity entity)\r\n
at Microsoft.EntityFrameworkCore.DbContext.SetEntityState[TEntity](TEntity entity, EntityState entityState)\r\n
at TestCaseManagementToolRepository.Implementation.Repositories.Repository`2.UpdateAsync(TEntity[] entity)
in D:\\sourcecode\\Repositories\\Repository.cs:line 62\r\n
at Project.Service.Implementation.Services.TestRunService.UpdateTestRunAsync(TestRunUpdateRequestModel testRun)
in D:\\sourcecode\\MyService\\Services\\TestRunService.cs:line 342\r\n
at Project.Controllers.MyController.Update(MyModel myModel)
in D:\\sourcecode\\Project\\Controllers\\MyController.cs:line 81\r\n
at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)\r\n
at System.Threading.Tasks.ValueTask`1.get_Result()\r\n
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()\r\n
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()\r\n
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)\r\n
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)\r\n
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()\r\n
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextExceptionFilterAsync()
We can set the entity’s state to modified using following code:
_context.Entry(e).State = EntityState.Modified;
For UpdateRange, we have to loop through all the entities to set their state to modified:
entities.ToList().ForEach(e =>
{
_context.Entry(e).State = EntityState.Modified;
});