Skip to content

Commit

Permalink
Fix to #27228 - EF Core 6.0 temporal tables - Support specifying prec…
Browse files Browse the repository at this point in the history
…ision for PeriodEnd and PeriodStart columns

Added HasPrecision builder methods for temporal period columns and fixed validation so that it can recognize custom precision.

Fixes #27228
  • Loading branch information
maumar committed Aug 10, 2022
1 parent b85b83f commit afd4bbe
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,14 @@ private static void ValidateTemporalPeriodProperty(IEntityType temporalEntityTyp
temporalEntityType.DisplayName(), periodProperty.Name, nameof(DateTime)));
}

const string expectedPeriodColumnName = "datetime2";
const string expectedPeriodColumnNameWithoutPrecision = "datetime2";
const string expectedPeriodColumnNameWithPrecision = "datetime2({0})";

var precision = periodProperty.GetPrecision();
var expectedPeriodColumnName = precision != null
? string.Format(expectedPeriodColumnNameWithPrecision, precision.Value)
: expectedPeriodColumnNameWithoutPrecision;

if (periodProperty.GetColumnType() != expectedPeriodColumnName)
{
throw new InvalidOperationException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,22 @@ public virtual OwnedNavigationTemporalPeriodPropertyBuilder HasColumnName(string
return this;
}

/// <summary>
/// Configures the precision of the period property.
/// </summary>
/// <remarks>
/// See <see href="https://aka.ms/efcore-docs-temporal">Using SQL Server temporal tables with EF Core</see>
/// for more information.
/// </remarks>
/// <param name="precision">The precision of the period property.</param>
/// <returns>The same builder instance so that multiple calls can be chained.</returns>
public virtual OwnedNavigationTemporalPeriodPropertyBuilder HasPrecision(int precision)
{
_propertyBuilder.HasPrecision(precision);

return this;
}

#region Hidden System.Object members

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,22 @@ public virtual TemporalPeriodPropertyBuilder HasColumnName(string name)
return this;
}

/// <summary>
/// Configures the precision of the period property.
/// </summary>
/// <remarks>
/// See <see href="https://aka.ms/efcore-docs-temporal">Using SQL Server temporal tables with EF Core</see>
/// for more information.
/// </remarks>
/// <param name="precision">The precision of the period property.</param>
/// <returns>The same builder instance so that multiple calls can be chained.</returns>
public virtual TemporalPeriodPropertyBuilder HasPrecision(int precision)
{
_propertyBuilder.HasPrecision(precision);

return this;
}

#region Hidden System.Object members

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ protected override string StoreName
protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context)
{
modelBuilder.Entity<City>().ToTable(tb => tb.IsTemporal());
modelBuilder.Entity<CogTag>().ToTable(tb => tb.IsTemporal());
modelBuilder.Entity<CogTag>().ToTable(tb => tb.IsTemporal(ttb =>
{
ttb.HasPeriodStart("PeriodStart").HasPrecision(0);
ttb.HasPeriodEnd("PeriodEnd").HasPrecision(0);
}));
modelBuilder.Entity<Faction>().ToTable(tb => tb.IsTemporal());
modelBuilder.Entity<Gear>().ToTable(tb => tb.IsTemporal());
modelBuilder.Entity<LocustLeader>().ToTable(tb => tb.IsTemporal());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -904,6 +904,19 @@ public void Temporal_doesnt_work_on_table_splitting_when_some_types_are_temporal
VerifyError(SqlServerStrings.TemporalAllEntitiesMappedToSameTableMustBeTemporal("Splitting1"), modelBuilder);
}

[ConditionalFact]
public void Temporal_table_with_explicit_precision_on_period_columns_passes_validation()
{
var modelBuilder = CreateConventionModelBuilder();
modelBuilder.Entity<Human>().ToTable(tb => tb.IsTemporal(ttb =>
{
ttb.HasPeriodStart("Start").HasPrecision(2);
ttb.HasPeriodEnd("End").HasPrecision(2);
}));

Validate(modelBuilder);
}

public class Human
{
public int Id { get; set; }
Expand Down

0 comments on commit afd4bbe

Please sign in to comment.