Hello
i'm trying to update record but must be sure to prevent updating some fields so i retrieve the old record before editing but i got this error nHandling.AbpApiExceptionFilterAttribute - Attaching an entity of type 'Umbrella.Models.Patient.Patient' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.
protected virtual async Task EditRecordAsync(CreateOrEditPatientDto input)
{
Debug.Assert(input.Patient.Id != null, "input.Patient.Id should be set.");
var patient = input.Patient.MapTo<Models.Patient.Patient>();
//Make sure some fields not editied in patien object
var oldPatient = await _patientRepository.GetAsync(patient.Id);
patient.IsActive = oldPatient.IsActive;
patient.IsCertified = oldPatient.IsCertified;
patient.ParentId = oldPatient.ParentId;
patient.DateEnd = oldPatient.DateEnd;
await _patientRepository.UpdateAsync(patient); // the error been thrown at this line
await _unitOfWorkManager.Current.SaveChangesAsync();
input.User.Name = input.Patient.NameAr;
input.User.Surname = input.Patient.NameEn;
Debug.Assert(input.User.Id != null, "input.User.Id should be set.");
var user = await UserManager.FindByIdAsync(input.User.Id.Value);
//Update user properties
input.User.MapTo(user);
CheckErrors(await UserManager.UpdateAsync(user));
}
if i removed these lines it work fine
var oldPatient = await _patientRepository.GetAsync(patient.Id);
patient.IsActive = oldPatient.IsActive;
patient.IsCertified = oldPatient.IsCertified;
patient.ParentId = oldPatient.ParentId;
patient.DateEnd = oldPatient.DateEnd;
but i need to do this anyway what's wrong with my code as i faced this error many times ?
3 Answer(s)
-
0
actually this issue help me to fix my problem [https://github.com/aspnetboilerplate/aspnetboilerplate/issues/1354])
but i don't what i'm doing in the previous snippet of code is right or not is there any way to exclude some properties from being mapped or updated what is the good practice for such a cases ? thank you
-
0
Hi,
var oldPatient = await _patientRepository.GetAsync(patient.Id);
This adds the patient entity to the context.
await _patientRepository.UpdateAsync(patient);
This tries to add another patient entity (with same id) to the context.
First of all, this is related to usage of EF (you will get the same exception in any project with EF, not related to AspNet Zero).
You have 2 options for best practice:
- Remove the unwanted properties from DTO. Thus, they will not be mapped. Optionally, you can configure AutoMapper to ignore these properties. I suggest this approach.
Then you can get entity from repository and override (map) with the input DTO.
var patient = await _patientRepository.GetAsync(input.Patient.Id); input.Patient.MapTo(patient);
Even no need to call repository.Update method (document: <a class="postlink" href="http://www.aspnetboilerplate.com/Pages/Documents/Unit-Of-Work#DocAutoSaveChanges">http://www.aspnetboilerplate.com/Pages/ ... aveChanges</a>)
- If you can not delete these proeprties from DTO; Get entity from repository, set input's propeties from entity and map input to entity.
-
0
Thank you for your advice
i'll let you know my progress