From b08bfb0e04df55586fcfa21195f783760deb15ac Mon Sep 17 00:00:00 2001 From: Arthur Vickers Date: Thu, 14 Oct 2021 11:33:22 +0100 Subject: [PATCH] [6.0] Flag all properties as not unknown when saving changes Fixes #26330 --- .../Internal/InternalEntityEntry.cs | 1 + .../GraphUpdates/GraphUpdatesTestBase.cs | 33 ++++++++++++ .../GraphUpdatesTestBaseMiscellaneous.cs | 53 +++++++++++++++++++ .../GraphUpdatesSqlServerOwnedTest.cs | 4 ++ 4 files changed, 91 insertions(+) diff --git a/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs b/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs index 815a782cdd2..31fd7530011 100644 --- a/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs +++ b/src/EFCore/ChangeTracking/Internal/InternalEntityEntry.cs @@ -1436,6 +1436,7 @@ public void AcceptChanges() } _stateData.FlagAllProperties(EntityType.PropertyCount(), PropertyFlag.IsTemporary, false); + _stateData.FlagAllProperties(EntityType.PropertyCount(), PropertyFlag.Unknown, false); var currentState = EntityState; if ((currentState == EntityState.Unchanged) diff --git a/test/EFCore.Specification.Tests/GraphUpdates/GraphUpdatesTestBase.cs b/test/EFCore.Specification.Tests/GraphUpdates/GraphUpdatesTestBase.cs index c99021eceae..2bb228a6baa 100644 --- a/test/EFCore.Specification.Tests/GraphUpdates/GraphUpdatesTestBase.cs +++ b/test/EFCore.Specification.Tests/GraphUpdates/GraphUpdatesTestBase.cs @@ -434,6 +434,10 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con b => b.HasKey("OwnerWithKeyedCollectionId", "PrivateKey")); }); + modelBuilder + .Entity() + .OwnsMany(e => e.Owned, owned => owned.HasKey("Id")); + modelBuilder.Entity( b => { @@ -3287,6 +3291,35 @@ public string Bar } } + protected class OwnerWithNonCompositeOwnedCollection : NotifyingEntity + { + private int _id; + private ICollection _owned = new ObservableHashSet(); + + public int Id + { + get => _id; + set => SetWithNotify(value, ref _id); + } + + public ICollection Owned + { + get => _owned; + set => SetWithNotify(value, ref _owned); + } + } + + protected class NonCompositeOwnedCollection : NotifyingEntity + { + private string _foo; + + public string Foo + { + get => _foo; + set => SetWithNotify(value, ref _foo); + } + } + protected class OwnerNoKeyGeneration : NotifyingEntity { private int _id; diff --git a/test/EFCore.Specification.Tests/GraphUpdates/GraphUpdatesTestBaseMiscellaneous.cs b/test/EFCore.Specification.Tests/GraphUpdates/GraphUpdatesTestBaseMiscellaneous.cs index 7e54281ab14..da40c4473e8 100644 --- a/test/EFCore.Specification.Tests/GraphUpdates/GraphUpdatesTestBaseMiscellaneous.cs +++ b/test/EFCore.Specification.Tests/GraphUpdates/GraphUpdatesTestBaseMiscellaneous.cs @@ -296,6 +296,59 @@ await ExecuteWithStrategyInTransactionAsync( }); } + [ConditionalTheory] // Issue #26330 + [InlineData(false)] + [InlineData(true)] + public virtual async Task Saving_unknown_key_value_marks_it_as_unmodified(bool async) + { + await ExecuteWithStrategyInTransactionAsync( + async context => + { + var owner = new OwnerWithNonCompositeOwnedCollection(); + owner.Owned.Add(new() { Foo = "Milan" }); + + if (async) + { + await context.AddAsync(owner); + await context.SaveChangesAsync(); + } + else + { + context.Add(owner); + context.SaveChanges(); + } + + owner.Owned.Remove(owner.Owned.Single()); + owner.Owned.Add(new() { Foo = "Rome" }); + + if (Fixture.ForceClientNoAction) + { + await Assert.ThrowsAsync( + async () => + _ = async + ? await context.SaveChangesAsync() + : context.SaveChanges()); + } + else + { + _ = async + ? await context.SaveChangesAsync() + : context.SaveChanges(); + } + }, + async context => + { + if (!Fixture.ForceClientNoAction) + { + var owner = async + ? await context.Set().SingleAsync() + : context.Set().Single(); + + Assert.Equal("Rome", owner.Owned.Single().Foo); + } + }); + } + [ConditionalTheory] // Issue #19856 [InlineData(false)] [InlineData(true)] diff --git a/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerOwnedTest.cs b/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerOwnedTest.cs index c64c766613f..92f93820967 100644 --- a/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerOwnedTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/GraphUpdates/GraphUpdatesSqlServerOwnedTest.cs @@ -454,6 +454,10 @@ protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext con b => b.HasKey("OwnerWithKeyedCollectionId", "PrivateKey")); }); + modelBuilder + .Entity() + .OwnsMany(e => e.Owned, owned => owned.HasKey("Id")); + modelBuilder.Entity( b => {