Skip to content

Commit

Permalink
Fix to #25511 - Temporal Tables: The given key 'SqlServer:TemporalHis…
Browse files Browse the repository at this point in the history
…toryTableName' was not present in the dictionary when creating migration on entity mapped to temporal table without explicitly providing history table name

Problem was that we don't store the default history table name in the annotation (like we do with default period property names), instead the getter on IReadOnlyEntityType retrieves the default value if needed.

Fix is to check if the history table annotation is present in the annotation list, just like we do with the history table schema.

Fixes #25511
  • Loading branch information
maumar committed Aug 13, 2021
1 parent 6eda37f commit b3619b4
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,10 @@ public SqlServerAnnotationCodeGenerator(AnnotationCodeGeneratorDependencies depe
if (annotations.TryGetValue(SqlServerAnnotationNames.IsTemporal, out var isTemporalAnnotation)
&& isTemporalAnnotation.Value as bool? == true)
{
var historyTableName = annotations[SqlServerAnnotationNames.TemporalHistoryTableName].Value as string;
var historyTableName = annotations.ContainsKey(SqlServerAnnotationNames.TemporalHistoryTableName)
? annotations[SqlServerAnnotationNames.TemporalHistoryTableName].Value as string
: null;

var historyTableSchema = annotations.ContainsKey(SqlServerAnnotationNames.TemporalHistoryTableSchema)
? annotations[SqlServerAnnotationNames.TemporalHistoryTableSchema].Value as string
: null;
Expand Down
56 changes: 56 additions & 0 deletions test/EFCore.Design.Tests/Migrations/ModelSnapshotSqlServerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1901,6 +1901,62 @@ public virtual void Temporal_table_information_is_stored_in_snapshot()
});
}

[ConditionalFact]
public virtual void Temporal_table_information_is_stored_in_snapshot_minimal_setup()
{
Test(
builder => builder.Entity<EntityWithStringProperty>().ToTable(tb => tb.IsTemporal()),
AddBoilerPlate(
GetHeading()
+ @"
modelBuilder.Entity(""Microsoft.EntityFrameworkCore.Migrations.ModelSnapshotSqlServerTest+EntityWithStringProperty"", b =>
{
b.Property<int>(""Id"")
.ValueGeneratedOnAdd()
.HasColumnType(""int"");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<int>(""Id""), 1L, 1);
b.Property<string>(""Name"")
.HasColumnType(""nvarchar(max)"");
b.Property<DateTime>(""PeriodEnd"")
.ValueGeneratedOnAddOrUpdate()
.HasColumnType(""datetime2"")
.HasColumnName(""PeriodEnd"");
b.Property<DateTime>(""PeriodStart"")
.ValueGeneratedOnAddOrUpdate()
.HasColumnType(""datetime2"")
.HasColumnName(""PeriodStart"");
b.HasKey(""Id"");
b.ToTable(""EntityWithStringProperty"");
b.ToTable(tb => tb.IsTemporal(ttb =>
{
ttb
.HasPeriodStart(""PeriodStart"")
.HasColumnName(""PeriodStart"");
ttb
.HasPeriodEnd(""PeriodEnd"")
.HasColumnName(""PeriodEnd"");
}
));
});", usingSystem: true),
o =>
{
var temporalEntity = o.FindEntityType("Microsoft.EntityFrameworkCore.Migrations.ModelSnapshotSqlServerTest+EntityWithStringProperty");
var annotations = temporalEntity.GetAnnotations().ToList();
Assert.Equal(5, annotations.Count);
Assert.Contains(annotations, a => a.Name == SqlServerAnnotationNames.IsTemporal && a.Value as bool? == true);
Assert.Contains(annotations, a => a.Name == SqlServerAnnotationNames.TemporalPeriodStartPropertyName && a.Value as string == "PeriodStart");
Assert.Contains(annotations, a => a.Name == SqlServerAnnotationNames.TemporalPeriodEndPropertyName && a.Value as string == "PeriodEnd");
});
}

#endregion

#region Owned types
Expand Down

0 comments on commit b3619b4

Please sign in to comment.