0

I have this error and I can't figure out why it is happening. Can someone help out?

The instance of entity type 'ApplicationUser' 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.

I checked the previous answers and all of them say that somewhere another instance is being used. But I have simplified code to 2 lines in the controller. This must be somewhere else, but I don't know where to look.

{
    [Route("api/user")]
    [ApiController]
    public class ApplicationUsersController : Controller
    {
        private readonly IEmailService _emailService;
        private readonly IIdentityService _identityService;
        private readonly IDbRepository<ApplicationUser> _userRepository;
        private readonly IMapper _mapper;
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly RoleManager<IdentityRole> _roleManager;

        private readonly IConfiguration _configuration;

        public ApplicationUsersController(
            IDbRepository<ApplicationUser> userRepository,
            IMapper mapper,
            UserManager<ApplicationUser> userManager,
            RoleManager<IdentityRole> roleManager,
            IEmailService emailService,
            IIdentityService identityService,
            IConfiguration configuration)
        {
            _userRepository = userRepository ?? throw new ArgumentNullException(nameof(userRepository));
            _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
            _userManager = userManager ?? throw new ArgumentNullException(nameof(userManager));
            _roleManager = roleManager ?? throw new ArgumentNullException(nameof(roleManager));
            _emailService = emailService ?? throw new ArgumentNullException(nameof(emailService));
            _identityService = identityService ?? throw new ArgumentNullException(nameof(identityService));
            _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
        }

    [HttpPut("{userId}")]
    [Authorize(Roles = GlobalConstants.AdminRole + "," + GlobalConstants.ManagerRole + "," + GlobalConstants.AppraiserRole)]
    public async Task<IActionResult> UpdatePasswordAndEmail([FromBody] 
    UserViewModel model, [FromRoute] string userId)
    {
        var user = await _userRepository.All().FirstOrDefaultAsync(x=>x.Id==userId);
        var res1 = await this._userManager.RemovePasswordAsync(user); // THIS LINE GIVES ERROR
        return Ok();
    }

}

Any help appreciated

I am registering the context as follows:

builder.RegisterType<AmritaDbContext>().As<IAmritaDbContext>().InstancePerLifetimeScope();

builder.RegisterGeneric(typeof(DbRepository<>)).As(typeof(IDbRepository<>)).InstancePerLifetimeScope();`

Configure from startup:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                // app.UseBrowserLink();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }


            app.UseCors("CorsPolicy");
            app.UseIdentityServer();
            app.UseHttpsRedirection();
            var option = new RewriteOptions();
            option.AddRedirect("^$", "swagger");
            app.UseRewriter(option);
            app.UseStaticFiles();

            
            ConfigureAuth(app);

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "api/v1/{controller=Home}/{action=Index}/{id?}");
            });

            var pathBase = Configuration["PATH_BASE"];

            app.UseSwagger()
               .UseSwaggerUI(c =>
               {
                   c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Amrita.API V1");
                   c.OAuthClientId("swaggerclient");
                   c.OAuthAppName("Amrita Swagger UI");
               });
        }

Configure from Identity Startup.cs:

 public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            // InitializeIdentityServerDatabase(app);

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseIdentityServer();

            app.UseStaticFiles();
            app.UseMvcWithDefaultRoute();
        }
mgPePe
  • 5,677
  • 12
  • 52
  • 85
  • Does this answer your question? [instance of entity type cannot be tracked because another instance with same key value is tracked](https://stackoverflow.com/questions/48202403/instance-of-entity-type-cannot-be-tracked-because-another-instance-with-same-key) –  Jun 29 '20 at 16:10
  • Unfortunately SO makes it look like I'm asking this, but to be clear, I've marked this as duplicate because the reason of the issue is the same. –  Jun 29 '20 at 16:16
  • I saw that answer and searched my code for `.AddSingleton<>` but I only got my mapper, which shouldn't be the problem. In other words, it looks like this is not the problem... – mgPePe Jun 29 '20 at 16:17
  • It doesn't have to be a singleton. The request is processed in a certain order of steps. And this error can occur when you use the context in multiple steps. Are you logging the request before calling the action? –  Jun 29 '20 at 16:26
  • I am not sure what you mean by `logging the request`? In my controller, you can see there is nothing before those lines. – mgPePe Jun 29 '20 at 16:28
  • Before the request is handled it passes through [middleware](https://learn.microsoft.com/nl-nl/aspnet/core/fundamentals/middleware/?view=aspnetcore-3.0#order). Do you have middleware where the context is used, e.g. for logging the request? –  Jun 29 '20 at 16:31
  • I updated the configure methods so you can see the middlewares. I don't see anything really custom written... is `ConfigureServices` relevant too, should I put that on? – mgPePe Jun 29 '20 at 16:36

1 Answers1

0

That error implies that the services you provide for IDbRepository<ApplicationUser> userRepository and UserManager<ApplicationUser> userManager are using the same DbContext instance.

You need to change the scope in which the DbContext is registered.

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
  • How can I do that? – mgPePe Jun 29 '20 at 15:38
  • You start by looking at where you register your dependencies. – CodeCaster Jun 29 '20 at 15:38
  • `builder.RegisterType().As().InstancePerLifetimeScope();` is this what I am looking for? – mgPePe Jun 29 '20 at 15:39
  • I don't think `InstancePerLifetimeScope()` is correct, but also the registration of the other types I mention in my answer are important. Edit your question to show all relevant code, at least where you register these dependencies. – CodeCaster Jun 29 '20 at 15:42
  • I tried `InstancePerRequest` but it throws another error. Should I use maybe something else, like `InstancePerDependency`? Nevermind, doesn't work either – mgPePe Jun 29 '20 at 15:43