微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

具有临时表的实体框架核心3.1-访问SysStartTime和SysEndTime

如何解决具有临时表的实体框架核心3.1-访问SysStartTime和SysEndTime

我已经基于Microsoft sql文档创建了时态表使用认历史记录表创建时态表

https://docs.microsoft.com/en-us/sql/relational-databases/tables/creating-a-system-versioned-temporal-table?view=sql-server-ver15#creating-a-temporal-table-with-a-default-history-table

迁移:

public partial class Temporaltables : Migration
{
    List<string> tablesToUpdate = new List<string>
        {
           "Images","Languages","Questions","Texts","Medias",};

    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.sql($"CREATE SCHEMA History");
        foreach (var table in tablesToUpdate)
        {
            string alterStatement = $@"ALTER TABLE [{table}] ADD SysstartTime datetime2(0) GENERATED ALWAYS AS ROW START HIDDEN
     CONSTRAINT DF_{table}_Sysstart DEFAULT GETDATE(),SysEndTime datetime2(0) GENERATED ALWAYS AS ROW END HIDDEN
     CONSTRAINT DF_{table}_SysEnd DEFAULT CONVERT(datetime2 (0),'9999-12-31 23:59:59'),PERIOD FOR SYstem_TIME (SysstartTime,SysEndTime)";
            migrationBuilder.sql(alterStatement);
            alterStatement = $@"ALTER TABLE [{table}] SET (SYstem_VERSIONING = ON (HISTORY_TABLE = History.[{table}]));";
            migrationBuilder.sql(alterStatement);
        }
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        foreach (var table in tablesToUpdate)
        {
            string alterStatement = $@"ALTER TABLE [{table}] SET (SYstem_VERSIONING = OFF);";
            migrationBuilder.sql(alterStatement);
            alterStatement = $@"ALTER TABLE [{table}] DROP PERIOD FOR SYstem_TIME";
            migrationBuilder.sql(alterStatement);
            alterStatement = $@"ALTER TABLE [{table}] DROP DF_{table}_Sysstart,DF_{table}_SysEnd";
            migrationBuilder.sql(alterStatement);
            alterStatement = $@"ALTER TABLE [{table}] DROP COLUMN SysstartTime,COLUMN SysEndTime";
            migrationBuilder.sql(alterStatement);
            alterStatement = $@"DROP TABLE History.[{table}]";
            migrationBuilder.sql(alterStatement);
        }
        migrationBuilder.sql($"DROP SCHEMA History");
    }
}

关于如何建立时态表的完整示例:

https://stackoverflow.com/a/64244548/3850405

这确实很好,但是现在我想访问SysstartTime的值。

我尝试过的事情:

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime SysstartTime { get; set; }

ApplicationDbContext.cs:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{...

    foreach (var et in modelBuilder.Model.GetEntityTypes())
    {
        foreach (var prop in et.GetProperties())
        {
            if (prop.Name == "SysstartTime" || prop.Name == "SysEndTime")
            {
                prop.ValueGenerated = Microsoft.EntityFrameworkCore.Metadata.ValueGenerated.OnAddOrUpdate;
            }
        }
    }

modelBuilder.Entity<Question>(e =>
{
    e.Property(p => p.SysstartTime).ValueGeneratedOnAddOrUpdate();
});

每次迁移都会导致以下结果:

migrationBuilder.AddColumn<DateTime>(
    name: "SysstartTime",table: "Questions",type: "datetime2(0)",nullable: false,defaultValue: new DateTime(1,1,DateTimeKind.Unspecified));

这当然会导致以下Update-Database命令的错误

每个表中的列名必须唯一。中的列名“ SysstartTime” 表“”已多次指定。

我一直在阅读这两个问题,并且似乎已经在Entity Framework Core 2.2中运行:

Net Core: Entity Framework and SQL Server Temporal Tables,Automatic Scaffolding

Entity Framework Core and SQL Server 2016 temporal tables

试图禁用“隐藏”功能,但没有帮助

sql

ALTER TABLE [dbo].Questions ALTER COLUMN SysstartTime DROP HIDDEN;

解决方法

对于已经具有列的表,我只是为迁移删除了var ans = File.ReadLines(@"Engines\" + url_engine_code) .SkipWhile(s => !s.TrimStart().StartsWith("[REG]")) // find line with [REG] .Skip(1) // skip line with [REG] .TakeWhile(s => !s.TrimStart().StartsWith("[LAP]")) .Where(s => s.Trim() != String.Empty) .ToList(); var ans2 = File.ReadLines(@"Engines\" + url_engine_code) .SkipWhile(s => !s.TrimStart().StartsWith("[LAP]")) // find line with [LAP] .Skip(1) // skip line with [LAP] .Where(s => s.Trim() != String.Empty) .ToList(); Up值,然后它起作用了:

Down

由于我以后不想编辑迁移生成的默认代码,因此决定对新实体执行以下操作:

通常向迁移添加migrationBuilder.AddColumn<DateTime>( name: "SysStartTime",table: "Questions",type: "datetime2(0)",nullable: false,defaultValue: new DateTime(1,1,DateTimeKind.Unspecified)); 值:

DateTime

ApplicationDbContext.cs:

public DateTime SysStartTime { get; set; }

public DateTime SysEndTime { get; set; }

迁移,如果您已经有protected override void OnModelCreating(ModelBuilder modelBuilder) {... foreach (var et in modelBuilder.Model.GetEntityTypes()) { foreach (var prop in et.GetProperties()) { if (prop.Name == "SysStartTime" || prop.Name == "SysEndTime") { prop.ValueGenerated = Microsoft.EntityFrameworkCore.Metadata.ValueGenerated.OnAddOrUpdate; } } } ,请删除这些行:

Schema History

在GitHub上的讨论:

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。