From c5c9b0ed48a59d1fec6140e93644b7cb08e6bb27 Mon Sep 17 00:00:00 2001 From: Arthur Vickers Date: Wed, 27 Jun 2018 17:50:56 -0700 Subject: [PATCH] [2.1.3] Add quirks for in-memory concurrency patch fix Issue #12214 --- .../Storage/Internal/InMemoryTable.cs | 20 +++-- .../UpdatesInMemoryTestBase.cs | 77 +++++++++++++++++++ 2 files changed, 91 insertions(+), 6 deletions(-) diff --git a/src/EFCore.InMemory/Storage/Internal/InMemoryTable.cs b/src/EFCore.InMemory/Storage/Internal/InMemoryTable.cs index fc2a2f8f0a6..17a1847020b 100644 --- a/src/EFCore.InMemory/Storage/Internal/InMemoryTable.cs +++ b/src/EFCore.InMemory/Storage/Internal/InMemoryTable.cs @@ -89,14 +89,22 @@ private static bool IsConcurrencyConflict( object rowValue, Dictionary concurrencyConflicts) { - if (property.IsConcurrencyToken - && !StructuralComparisons.StructuralEqualityComparer.Equals( - rowValue, - entry.GetOriginalValue(property))) + if (property.IsConcurrencyToken) { - concurrencyConflicts.Add(property, rowValue); + var originalValue = entry.GetOriginalValue(property); - return true; + var revertPatchBehavior = AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue12214", out var isEnabled) + && isEnabled; + + if ((revertPatchBehavior + && !Equals(rowValue, originalValue)) + || (!revertPatchBehavior + && !StructuralComparisons.StructuralEqualityComparer.Equals(rowValue, originalValue))) + { + concurrencyConflicts.Add(property, rowValue); + + return true; + } } return false; diff --git a/test/EFCore.InMemory.FunctionalTests/UpdatesInMemoryTestBase.cs b/test/EFCore.InMemory.FunctionalTests/UpdatesInMemoryTestBase.cs index 95f1663dd23..cfcf5e5cefd 100644 --- a/test/EFCore.InMemory.FunctionalTests/UpdatesInMemoryTestBase.cs +++ b/test/EFCore.InMemory.FunctionalTests/UpdatesInMemoryTestBase.cs @@ -9,6 +9,7 @@ using Microsoft.EntityFrameworkCore.InMemory.Internal; #endif using Microsoft.EntityFrameworkCore.TestModels.UpdatesModel; +using Xunit; namespace Microsoft.EntityFrameworkCore { @@ -20,6 +21,82 @@ protected UpdatesInMemoryTestBase(TFixture fixture) { } +#if !Test20 + [Fact] + public virtual void Update_on_bytes_concurrency_token_original_value_matches_throws_with_quirk() + { + var productId = new Guid("984ade3c-2f7b-4651-a351-642e92ab7146"); + + try + { + AppContext.SetSwitch("Microsoft.EntityFrameworkCore.Issue12214", true); + + ExecuteWithStrategyInTransaction( + context => + { + var entry = context.ProductWithBytes.Attach( + new ProductWithBytes + { + Id = productId, + Name = "MegaChips", + Bytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 } + }); + + entry.Entity.Name = "GigaChips"; + + Assert.Throws( + () => context.SaveChanges()); + }, + context => + { + Assert.Equal("MegaChips", context.ProductWithBytes.Find(productId).Name); + }); + + } + finally + { + AppContext.SetSwitch("Microsoft.EntityFrameworkCore.Issue12214", false); + } + } + + [Fact] + public virtual void Remove_on_bytes_concurrency_token_original_value_matches_throws_with_quirk() + { + var productId = new Guid("984ade3c-2f7b-4651-a351-642e92ab7146"); + + try + { + AppContext.SetSwitch("Microsoft.EntityFrameworkCore.Issue12214", true); + + ExecuteWithStrategyInTransaction( + context => + { + var entry = context.ProductWithBytes.Attach( + new ProductWithBytes + { + Id = productId, + Name = "MegaChips", + Bytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 } + }); + + entry.State = EntityState.Deleted; + + Assert.Throws( + () => context.SaveChanges()); + }, + context => + { + Assert.Equal("MegaChips", context.ProductWithBytes.Find(productId).Name); + }); + + } + finally + { + AppContext.SetSwitch("Microsoft.EntityFrameworkCore.Issue12214", false); + } + } +#endif + protected override string UpdateConcurrencyMessage => InMemoryStrings.UpdateConcurrencyException;