Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data seeding can leave tracked entities in the context #16025

Closed
samueleresca opened this issue Jun 10, 2019 · 3 comments · Fixed by #16368
Closed

Data seeding can leave tracked entities in the context #16025

samueleresca opened this issue Jun 10, 2019 · 3 comments · Fixed by #16368
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported type-bug
Milestone

Comments

@samueleresca
Copy link

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 ---

Steps to reproduce

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.

Further technical details

EF Core version: (found in project.csproj or packages.config)
Database Provider: Microsoft.EntityFrameworkCore.InMemory
Operating system: MacOSX
IDE: VsCode

@ajcvickers
Copy link
Member

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:

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();
}

samueleresca added a commit to PacktPublishing/Hands-On-RESTful-Web-Services-with-ASP.NET-Core-3 that referenced this issue Jun 11, 2019
@samueleresca
Copy link
Author

@ajcvickers thanks for the workaround

@AndriySvyryd
Copy link
Member

AndriySvyryd commented Jun 11, 2019

@ajcvickers fb84697 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.

@ajcvickers ajcvickers self-assigned this Jun 11, 2019
@ajcvickers ajcvickers added this to the 3.0.0 milestone Jun 14, 2019
@ajcvickers ajcvickers changed the title InMemory: The instance of entity type 'Item' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. Data seeding can leave tracked entities in the context Jul 1, 2019
@ajcvickers ajcvickers added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Jul 1, 2019
ajcvickers added a commit that referenced this issue Jul 1, 2019
ajcvickers added a commit that referenced this issue Jul 2, 2019
@ajcvickers ajcvickers modified the milestones: 3.0.0, 3.0.0-preview7 Jul 2, 2019
ajcvickers added a commit that referenced this issue Jul 2, 2019
@ajcvickers ajcvickers modified the milestones: 3.0.0, 3.0.0-preview8 Jul 29, 2019
@ajcvickers ajcvickers modified the milestones: 3.0.0-preview8, 3.0.0 Nov 11, 2019
@ajcvickers ajcvickers removed their assignment Sep 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported type-bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants