skip to Main Content

I want to map a DTO with the identity model (entity).

But I get the following error

InvalidOperationException: The instance of entity type ‘IdentityUser’ cannot be tracked because another instance with the same key value for {‘Id’} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using ‘DbContextOptionsBuilder.EnableSensitiveDataLogging’ to see the conflicting key values.

The code I have written:

 public static TypeAdapterConfig MapUserToUpdateUserDto()
 {
     var config = new TypeAdapterConfig();
     config.NewConfig<IdentityUser,UpdateUserDto>()
         .Map(e => e.PhoneNumber, d => d.PhoneNumber)
         .Map(e => e.Email, d => d.Email)
         .Map(e => e.UserName, d => d.UserName)
         .Map(e => e.Active, d => d.EmailConfirmed)
         .Map(e => e.Active, d => d.PhoneNumberConfirmed)
         .TwoWays();
     return config;
 }

 public async Task UpdateUser(UpdateUserDto model)
 {
     var user = await _userManager.FindByIdAsync(model.Id!);
     user = model.Adapt<IdentityUser>(UserMapster.MapUserToUpdateUserDto());
     
     var resultUpdateUser= await _userManager.UpdateAsync(user);

     if (resultUpdateUser.Succeeded)
     {
         if (!string.IsNullOrEmpty(model.Password) && !string.IsNullOrEmpty(model.PasswordConfirmed))
         {
             var token = await _userManager.GeneratePasswordResetTokenAsync(user);
             await _userManager.ResetPasswordAsync(user, token, model.Password);
         }

         var roles = await _userManager.GetRolesAsync(user!);

         await _userManager.RemoveFromRolesAsync(user, roles);
         await _userManager.AddToRolesAsync(user, model.Role!);
     }
 }

Thank you for helping me

2

Answers


  1. Chosen as BEST ANSWER

    Thank you, I changed my code to this and my problem was solved

     public async Task UpdateUser(UpdateUserDto model)
     {
         var user = await _userManager.FindByIdAsync(model.Id!);
         model.Adapt(user, UserMapster.MapUserToUpdateUserDto());
         var resultUpdateUser = await _userManager.UpdateAsync(user!);
         if (resultUpdateUser.Succeeded)
         {
             if (!string.IsNullOrEmpty(model.Password) && !string.IsNullOrEmpty(model.PasswordConfirmed))
             {
                 var token = await _userManager.GeneratePasswordResetTokenAsync(user);
                 await _userManager.ResetPasswordAsync(user, token, model.Password);
             }
    
             var roles = await _userManager.GetRolesAsync(user!);
    
             await _userManager.RemoveFromRolesAsync(user, roles);
             await _userManager.AddToRolesAsync(user, model.Role!);
         }
     }


  2. Change your UpdateUser method like below.

    Adapt the changes onto user, not replacing it.

     public async Task UpdateUser(UpdateUserDto model)
     {
         var user = await _userManager.FindByIdAsync(model.Id!);
         // Change your code here
         // adapt the changes onto it, not replacing the `user` 
         model.Adapt<IdentityUser>(UserMapster.MapUserToUpdateUserDto());
         
         var resultUpdateUser= await _userManager.UpdateAsync(user);
    
         if (resultUpdateUser.Succeeded)
         {
             if (!string.IsNullOrEmpty(model.Password) && !string.IsNullOrEmpty(model.PasswordConfirmed))
             {
                 var token = await _userManager.GeneratePasswordResetTokenAsync(user);
                 await _userManager.ResetPasswordAsync(user, token, model.Password);
             }
    
             var roles = await _userManager.GetRolesAsync(user!);
    
             await _userManager.RemoveFromRolesAsync(user, roles);
             await _userManager.AddToRolesAsync(user, model.Role!);
         }
     }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search