I'm getting this error in some unit tests using the last preview version (3.0.0-preview5.19227.1) of the Microsoft.EntityFrameworkCore.InMemory package. The same issue is not reproducible with the stable version 2.2.4.
The exception that I'm receiving:
Exception message: System.ArgumentException : An item with the same key has already been added. Key: 3eb00b42-a9f0-4012-841d-70ebf3ab7474
Stack trace: at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
at Microsoft.EntityFrameworkCore.InMemory.Storage.Internal.InMemoryTable`1.Create(IUpdateEntry entry)
at Microsoft.EntityFrameworkCore.InMemory.Storage.Internal.InMemoryStore.ExecuteTransaction(IList`1 entries, IDiagnosticsLogger`1 updateLogger)
at Microsoft.EntityFrameworkCore.InMemory.Storage.Internal.InMemoryDatabase.SaveChangesAsync(IList`1 entries, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList`1 entriesToSave, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at VinylStore.Catalog.Infrastructure.CatalogContext.SaveEntitiesAsync(CancellationToken cancellationToken) in /Users/samuele.resca/Projects/EFCore.IssueSample/Catalog/src/VinylStore.Catalog.Infrastructure/CatalogContext.cs:line 27
at VinylStore.Catalog.Infrastructure.Tests.ItemRepositoryTests.should_add_new_item(String jsonEntity) in /Users/samuele.resca/Projects/EFCore.IssueSample/Catalog/tests/VinylStore.Catalog.Infrastructure.Tests/ItemRepositoryTests.cs:line 89
--- End of stack trace from previous location where exception was thrown ---
Failed VinylStore.Catalog.Infrastructure.Tests.ItemRepositoryTests.should_update_item(jsonEntity: "{ \"Id\": \"b5b05534-9263-448c-a69e-0bbd8b3eb90e\""...)
Error Message:
System.InvalidOperationException : The instance of entity type 'Item' 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.
Stack Trace:
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, Boolean modifyProperties)
at Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry.set_State(EntityState value)
at VinylStore.Catalog.Infrastructure.Repositories.ItemRepository.Update(Item item) in /Users/samuele.resca/Projects/EFCore.IssueSample/Catalog/src/VinylStore.Catalog.Infrastructure/Repositories/ItemRepository.cs:line 48
at VinylStore.Catalog.Infrastructure.Tests.ItemRepositoryTests.should_update_item(String jsonEntity) in /Users/samuele.resca/Projects/EFCore.IssueSample/Catalog/tests/VinylStore.Catalog.Infrastructure.Tests/ItemRepositoryTests.cs:line 118
--- End of stack trace from previous location where exception was thrown ---
The following repository contains the issue: EFCore.IssueSamples
To reproduce the error execute inside the project folder:
dotnet build
dotnet test
If you revert to the 2.2.4 version, all the packages it works fine.
I've tested both the int type and the Guid type.
EF Core version: (found in project.csproj or packages.config)
Database Provider: Microsoft.EntityFrameworkCore.InMemory
Operating system: MacOSX
IDE: VsCode
Note for triage: the issue here is that the context instance is still tracking seed data after EnsureCreated is called. /cc @AndriySvyryd
@samueleresca As a workaround for now you can move your EnsureCreated to run on a separate context instance. For example:
```C#
using (var context = new TestCatalogContext(options))
{
context.Database.EnsureCreated();
}
using (var context = new TestCatalogContext(options))
{
var sut = new ItemRepository(context);
sut.Add(entity);
await sut.UnitOfWork.SaveEntitiesAsync();
}
```
@ajcvickers thanks for the workaround
@ajcvickers fb846974a4f25a386a224342f26daecae2cc1bea changed creating a new StateManager to creating an UpdateAdapterFactory with the shared StateManager instance when called without a model (InMemory and Cosmos). The fix would be to pass in the model instance.