Skip to content

Commit 1e32073

Browse files
authored
Fix to #29902 - Renaming PeriodStart and PeriodEnd columns of a temporal table causes them to be swapped (#32328)
Problem was that migration model differ was too lax with pairing up columns. Fix is to add more predicates - one that matches annotations+values and one that just matches annotations, ignoring the values, before we fallback to simple column definition. Now that we reworked temporal annotations, this actually gives clean match for the period start and period end column. Moreover, this change could improve matching in other, non-temporal scenarios. Fixes #29902
1 parent f55b4a0 commit 1e32073

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

src/EFCore.Relational/Migrations/Internal/MigrationsModelDiffer.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -929,8 +929,52 @@ protected virtual IEnumerable<MigrationOperation> Diff(
929929
tm =>
930930
string.Equals(sm.Property.Name, tm.Property.Name, StringComparison.OrdinalIgnoreCase)
931931
&& EntityTypePathEquals(sm.Property.DeclaringType, tm.Property.DeclaringType, c))),
932+
(s, t, _) => ColumnStructureEquals(s, t) && ColumnAnnotationsEqual(s, t, matchValues: true),
933+
(s, t, _) => ColumnStructureEquals(s, t) && ColumnAnnotationsEqual(s, t, matchValues: false),
932934
(s, t, _) => ColumnStructureEquals(s, t));
933935

936+
private static bool ColumnAnnotationsEqual(IColumn source, IColumn target, bool matchValues)
937+
{
938+
var sourceAnnotations = source.GetAnnotations().ToList();
939+
var targetAnnotations = target.GetAnnotations().ToList();
940+
941+
if (sourceAnnotations.Count != targetAnnotations.Count)
942+
{
943+
return false;
944+
}
945+
946+
foreach (var sourceAnnotation in sourceAnnotations)
947+
{
948+
var matchFound = false;
949+
for (var i = 0; i < targetAnnotations.Count; i++)
950+
{
951+
var targetAnnotation = targetAnnotations[i];
952+
953+
if (sourceAnnotation.Name != targetAnnotation.Name)
954+
{
955+
continue;
956+
}
957+
958+
if (matchValues && sourceAnnotation.Value != targetAnnotation.Value)
959+
{
960+
continue;
961+
}
962+
963+
targetAnnotations.RemoveAt(i);
964+
matchFound = true;
965+
966+
break;
967+
}
968+
969+
if (!matchFound)
970+
{
971+
return false;
972+
}
973+
}
974+
975+
return true;
976+
}
977+
934978
private static bool ColumnStructureEquals(IColumn source, IColumn target)
935979
{
936980
if (!source.TryGetDefaultValue(out var sourceDefault))

test/EFCore.SqlServer.FunctionalTests/Migrations/MigrationsSqlServerTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8429,7 +8429,7 @@ await Test(
84298429
""");
84308430
}
84318431

8432-
[ConditionalFact(Skip = "issue #29902")]
8432+
[ConditionalFact]
84338433
public virtual async Task Change_names_of_period_columns_in_temporal_table()
84348434
{
84358435
await Test(

0 commit comments

Comments
 (0)