From 6d4a1b374324be5fe6c7c9c576a05ac038979daa Mon Sep 17 00:00:00 2001 From: Arthur Vickers Date: Fri, 30 Jun 2017 15:15:21 -0700 Subject: [PATCH] Stop returning detached entries from the ChangeTracker Issue #8921 --- .../ChangeTracking/Internal/StateManager.cs | 3 ++- .../ChangeTracking/EntityEntryTest.cs | 24 +++++++++++++++++++ .../Internal/StateManagerTest.cs | 19 +++++++++++---- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/EFCore/ChangeTracking/Internal/StateManager.cs b/src/EFCore/ChangeTracking/Internal/StateManager.cs index 6b790562a4e..4bc1c8b1294 100644 --- a/src/EFCore/ChangeTracking/Internal/StateManager.cs +++ b/src/EFCore/ChangeTracking/Internal/StateManager.cs @@ -377,7 +377,8 @@ private IIdentityMap FindIdentityMap(IKey key) /// directly from your code. This API may change or be removed in future releases. /// public virtual IEnumerable Entries => _entityReferenceMap.Values - .Concat(_dietReferenceMap.Values.SelectMany(e => e.Values)); + .Concat(_dietReferenceMap.Values.SelectMany(e => e.Values)) + .Where(e => e.EntityState != EntityState.Detached); /// /// This API supports the Entity Framework Core infrastructure and is not intended to be used diff --git a/test/EFCore.Tests/ChangeTracking/EntityEntryTest.cs b/test/EFCore.Tests/ChangeTracking/EntityEntryTest.cs index ede7f2b6439..d9e772b5b08 100644 --- a/test/EFCore.Tests/ChangeTracking/EntityEntryTest.cs +++ b/test/EFCore.Tests/ChangeTracking/EntityEntryTest.cs @@ -128,6 +128,30 @@ protected internal override void OnModelCreating(ModelBuilder modelBuilder) } } + [Fact] + public void Detached_entities_are_not_returned_from_the_change_tracker() + { + using (var context = new FreezerContext()) + { + var entity = new Chunky { Id = 808 }; + context.Attach(entity); + + Assert.Equal(1, context.ChangeTracker.Entries().Count()); + + context.Entry(entity).State = EntityState.Detached; + + Assert.Equal(0, context.ChangeTracker.Entries().Count()); + + context.ChangeTracker.DetectChanges(); + + Assert.Equal(0, context.ChangeTracker.Entries().Count()); + + context.Entry(entity); + + Assert.Equal(0, context.ChangeTracker.Entries().Count()); + } + } + [Fact] public void Can_obtain_entity_instance() { diff --git a/test/EFCore.Tests/ChangeTracking/Internal/StateManagerTest.cs b/test/EFCore.Tests/ChangeTracking/Internal/StateManagerTest.cs index c912e7268af..2e2a3c343c2 100644 --- a/test/EFCore.Tests/ChangeTracking/Internal/StateManagerTest.cs +++ b/test/EFCore.Tests/ChangeTracking/Internal/StateManagerTest.cs @@ -563,10 +563,21 @@ public void Can_get_all_entities() var productId1 = new Guid("984ade3c-2f7b-4651-a351-642e92ab7146"); var productId2 = new Guid("0edc9136-7eed-463b-9b97-bdb9648ab877"); - stateManager.StartTracking(stateManager.GetOrCreateEntry(new Category { Id = 77, PrincipalId = 777 })); - stateManager.StartTracking(stateManager.GetOrCreateEntry(new Category { Id = 78, PrincipalId = 778 })); - stateManager.StartTracking(stateManager.GetOrCreateEntry(new Product { Id = productId1 })); - stateManager.StartTracking(stateManager.GetOrCreateEntry(new Product { Id = productId2 })); + stateManager.StartTracking( + stateManager.GetOrCreateEntry(new Category { Id = 77, PrincipalId = 777 })) + .SetEntityState(EntityState.Unchanged); + + stateManager.StartTracking( + stateManager.GetOrCreateEntry(new Category { Id = 78, PrincipalId = 778 })) + .SetEntityState(EntityState.Unchanged); + + stateManager.StartTracking( + stateManager.GetOrCreateEntry(new Product { Id = productId1 })) + .SetEntityState(EntityState.Unchanged); + + stateManager.StartTracking( + stateManager.GetOrCreateEntry(new Product { Id = productId2 })) + .SetEntityState(EntityState.Unchanged); Assert.Equal(4, stateManager.Entries.Count());