The instance of entity type cannot be tracked because another instance with the same key value for {'Id'} is already being tracked

See original GitHub issue

I am aware that such question has already been asked numerous times, but solutions did not help me. I try to unit test my code in XUnit, but have numerous issues with EF Core, here is one of them.

// db init
public static StoreContext ConfigureStoreContext(IServiceCollection services, ITestOutputHelper output)
{
        services.AddDbContext<StoreContext>(c =>
            c.UseInMemoryDatabase(Guid.NewGuid().ToString()));

        var serviceProvider = services.BuildServiceProvider();
        var context = serviceProvider.GetRequiredService<StoreContext>();
        StoreContextSeed.SeedStoreAsync(context);
        return context;
}

[Fact]
public async Task UpdateAsync()
{
    string newTitle = "newTitle1";
    int newBrandId = 3;
    //var item = await storeContext.Items.AsNoTracking().FirstOrDefaultAsync(); // result is the same
    var item = new Item()
    {
        Id = 1,
        BrandId = newBrandId,
        CategoryId = 1,
        MeasurementUnitId = 1,
        StoreId = 1,
        Title = newTitle
    };
    storeContext.Entry(item).State = EntityState.Detached; // has no effect, could be removed. 
    //if assign Deleted, then get error "can not update deleted item"
    await service.UpdateAsync(item); // exception inside
    var updatedItem = await storeContext.Items.AsNoTracking().FirstOrDefaultAsync();
    Assert.Equal(newTitle, updatedItem.Title);
    Assert.Equal(newBrandId, updatedItem.BrandId);
}

public async Task UpdateAsync(T entity)
{
    _dbContext.Entry(entity).State = EntityState.Modified; // exception when trying to change the state
    await _dbContext.SaveChangesAsync();
}

Further technical details

EF Core version: 2.1 Database Provider: InMemory Operating system: IDE: (Visual Studio 2017 15.7)

Test Name:	UnitTests.Services.StoreServiceTests.UpdateAsync
Test FullName:	UnitTests.Services.StoreServiceTests.UpdateAsync
Test Source:	C:\Users\kozachenkoav\source\repos\OctopusStore\UnitTests\Services\StoreServiceTests.cs : line 56
Test Outcome:	Failed
Test Duration:	0:00:02,242

Result StackTrace:	
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.ThrowIdentityConflict(InternalEntityEntry entry)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IdentityMap`1.Add(TKey key, InternalEntityEntry entry, Boolean updateDuplicate)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTracking(InternalEntityEntry entry)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.SetEntityState(EntityState oldState, EntityState newState, Boolean acceptChanges)
   at Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry.set_State(EntityState value)
   at Infrastructure.Data.EfRepository`1.UpdateAsync(T entity) in C:\Users\kozachenkoav\source\repos\OctopusStore\Infrastructure\Data\EfRepository.cs:line 54
   at Infrastructure.Services.StoreService.UpdateAsync(Store store) in C:\Users\kozachenkoav\source\repos\OctopusStore\Infrastructure\Services\StoreService.cs:line 29
   at UnitTests.Services.StoreServiceTests.UpdateAsync() in C:\Users\kozachenkoav\source\repos\OctopusStore\UnitTests\Services\StoreServiceTests.cs:line 71
--- End of stack trace from previous location where exception was thrown ---
Result Message:	System.InvalidOperationException : The instance of entity type 'Store' 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

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:52
  • Comments:41 (3 by maintainers)

github_iconTop GitHub Comments

38reactions
phil123456commented, Sep 7, 2020

what’s the point of using EF if, instead of writing queries, you have to write additional code to avoid such bollocks ??

34reactions
alexandr-ospreycommented, Jun 25, 2018

Numerous issues I’ve been running into have one nasty root. In a nutshell: I’ve learned the hard way why dbContext is scoped rather than singleton. Here is Store type, but the issue was the same. Here is simplified test initialization code

    public TestBase()
    {
        services = new ServiceCollection();
        storeContext = StoreContextMock.ConfigureStoreContext(services, output);
        serviceProvider = services.BuildServiceProvider();
    }
    public static StoreContext ConfigureStoreContext(IServiceCollection services)
    {
        services.AddDbContext<StoreContext>(c =>
            c.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking));

        var serviceProvider = services.BuildServiceProvider();
        var storeContext = serviceProvider.GetRequiredService<StoreContext>();
        storeContext .Stores.Add(new Store { Title = "John's store", Address = "NY", Description = "Electronics best deals", SellerId = "john@mail.com" });
        storeContext .Stores.Add(new Store { Title = "Jennifer's store", Address = "Sydney", Description = "Fashion", SellerId = "jennifer@mail.com" });
        storeContext .SaveChanges();
        return storeContext ;
    }

I reread error and finally noticed the main word

The instance of entity type ‘Store’ cannot be tracked because another instance with the same key value for {‘Id’} is already being tracked

So there has to be some orphan tracked instance preventing me from working with store. I did not save any references to s1 or s2, so it must be storeContext storing references on inserted objects even after leaving scope of their declaration and initialization. That’s why I was unable update variables normally and also why my ‘queried’ from db objects had all their navigation properties assigned (lazy loading has little to do with this). The following code resolved all my issues.

    public static StoreContext ConfigureStoreContext(IServiceCollection services)
    {
        services.AddDbContext<StoreContext>(c =>
            c.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking));

        var serviceProvider = services.BuildServiceProvider();
        var storeContext = serviceProvider.GetRequiredService<StoreContext>();
        var s1 = new Store { Title = "John's store", Address = "NY", Description = "Electronics best deals", SellerId = "john@mail.com" };
        var s2 = new Store { Title = "Jennifer's store", Address = "Sydney", Description = "Fashion", SellerId = "jennifer@mail.com" }
        storeContext.Stores.Add(s1);
        storeContext.Stores.Add(s2);
        storeContext.Entry<Store>(s1).State = EntityState.Detached;
        storeContext.Entry<Store>(s2).State = EntityState.Detached;
        storeContext.SaveChanges();
        return storeContext;
    }

That is one of many reasons why dbContext should be limited by a scope. Thanks for the hint.

Read more comments on GitHub >

github_iconTop Results From Across the Web

The instance of entity type cannot be tracked because ...
I had this problem myself. Entity Framework keeps track of every object you insert into the database. So when you insert a duplicate...
Read more >
The instance of entity type cannot be tracked because ...
The instance of entity type cannot be tracked because another instance with the same key value for { 'ID'} is already being tracked....
Read more >
Error In Update Record (The instance of entity type 'x' ...
The instance of entity type 'ApplicationRole' cannot be tracked because another instance with the same key value for {'Id'} is already being ......
Read more >
instance of entity type cannot be tracked because ... - YouTube
instance of entity type cannot be tracked because another instance with same key value is tracked - EF Core.
Read more >
Entity Framework Error - Entity Type Cannot be Tracked
InvalidOperationException: 'The instance of entity type 'SomeData' cannot be tracked because another instance with the same key value for {'Id'} ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found