EF Core 6.0 时态表 - Add-Migration - Period 属性 'Comment.PeriodStart' must be a shadow 属性

EF Core 6.0 temporal tables - Add-Migration - Period property 'Comment.PeriodStart' must be a shadow property

我们最近将项目升级到 Microsoft.EntityFrameworkCore 6.0.0。此版本使 SQL 服务器临时 table 开箱即用。

https://devblogs.microsoft.com/dotnet/prime-your-flux-capacitor-sql-server-temporal-tables-in-ef-core-6-0/

自 Entity Framework Core 3.1 以来,我们一直使用时间 tables,使用此处所述的自定义迁移:

仅仅遵循 Microsoft 的指南当然是行不通的,因为默认的列名是 PeriodStartPeriodEnd 而不是我们的 SysStartTimeSysEndTime。历史记录 table 名称也不匹配。

modelBuilder
    .Entity<Comment>()
    .ToTable("Comments", b => b.IsTemporal());

已创建迁移:

protected override void Up(MigrationBuilder migrationBuilder)
{
    migrationBuilder.AlterTable(
        name: "Comments")
        .Annotation("SqlServer:IsTemporal", true)
        .Annotation("SqlServer:TemporalHistoryTableName", "CommentsHistory")
        .Annotation("SqlServer:TemporalHistoryTableSchema", null)
        .Annotation("SqlServer:TemporalPeriodEndColumnName", "PeriodEnd")
        .Annotation("SqlServer:TemporalPeriodStartColumnName", "PeriodStart");

    migrationBuilder.AddColumn<DateTime>(
        name: "PeriodEnd",
        table: "Comments",
        type: "datetime2",
        nullable: false,
        defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified))
        .Annotation("SqlServer:IsTemporal", true)
        .Annotation("SqlServer:TemporalPeriodEndColumnName", "PeriodEnd")
        .Annotation("SqlServer:TemporalPeriodStartColumnName", "PeriodStart");

    migrationBuilder.AddColumn<DateTime>(
        name: "PeriodStart",
        table: "Comments",
        type: "datetime2",
        nullable: false,
        defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified))
        .Annotation("SqlServer:IsTemporal", true)
        .Annotation("SqlServer:TemporalPeriodEndColumnName", "PeriodEnd")
        .Annotation("SqlServer:TemporalPeriodStartColumnName", "PeriodStart");
}

创建自定义转换应该可以解决此问题,如下所述:

modelBuilder
    .Entity<Comment>()
    .ToTable("Comments", tb => tb.IsTemporal(temp =>
    {
        temp.UseHistoryTable("Comments", "History");
        temp.HasPeriodStart("SysStartTime");
        temp.HasPeriodEnd("SysEndTime");
    }));

https://coderedirect.com/questions/540979/how-can-i-use-system-versioned-temporal-table-with-entity-framework

然而,当我这样做时,Add-Migration 命令出现以下错误:

Period property 'Comment.SysStartTime' must be a shadow property.

为了验证我恢复到的任何其他代码没有问题:

modelBuilder
    .Entity<Comment>()
    .ToTable("Comments", b => b.IsTemporal());

然后将public DateTime PeriodStart { get; set; }添加到Comment

然后我收到错误:

Period property 'Comment.PeriodStart' must be a shadow property.

有什么办法可以解决这个问题吗?我们使用我们的 SysStartTime 作为最后一个 modified/last 更新值并且它工作得很好。必须通过 EF.Property<DateTime>(comment, "SysStartTime")) 包含它似乎非常不必要,因为该列同时存在于时间 table 和原始 table.

无法在 EF Core 6.0 中修复。

来自@ajcvickers,Entity Framework 的工程经理:

Unfortunately, there isn't any workaround for this that allows both the use of the new temporal table features, and mapping the period columns to non-shadow properties.

https://github.com/dotnet/efcore/issues/26960#issuecomment-991867756

如果您想在 EF Core 7.0 中看到此功能,请在下方投票:

https://github.com/dotnet/efcore/issues/26463