【问题标题】:Enity Framework revertable migrations with data changes?具有数据更改的实体框架可恢复迁移?
【发布时间】:2019-08-05 05:10:21
【问题描述】:

如果您创建一个仅更改表结构的迁移,您肯定可以轻松恢复迁移,因为它有 Up()Down() 方法。

但是如果我们有一些似乎不可恢复的数据更改呢?

例如,现在我有一个可以为空的列,其中包含 Enum 值。

Paid column
---
Paid = 0
PaidTill = 1
NotPaid = 2
(+ NULL value)

所以有 4 个值。现在我想将此列更改为只有 2 个值,并且此列不再可以为空:

Paid column
---
NotPaid = 0
Paid = 1

因此,如果值为 NULL,它将为 NotPaidPaidTill 变为 Paid,依此类推。

我知道我可以使用数据操作 SQL 扩展 Up() 方法,但是这种迁移可以恢复吗?

【问题讨论】:

    标签: c# .net sql-server entity-framework entity-framework-6


    【解决方案1】:

    您描述的数据操作显然会丢失数据。除非您可以根据系统中的其他数据扣除原始值,否则无法还原它。

    如果您没有其他数据,您可以在迁移过程中创建它。备份Up 方法中的原始值(复制到单独的列/表/模式/数据库)。在Down方法中,从备份中读取原始值,并删除备份:

    protected override void Up(MigrationBuilder migrationBuilder)
    {
        // before any manipulations:
        // create a backup table and copy data from the original column
        // assuming MyId is the primary key in the original table
    
        migrationBuilder.Sql(@"
            SELECT *
            INTO MyNewBackupTable
            FROM (SELECT MyId, MyNullableColumn FROM MyOriginalTable)
        "); 
    
        // ... perform the desired manipulations 
    }
    
    protected override void Down(MigrationBuilder migrationBuilder)
    {
        // ... revert other manipulations,
        // (including making the column nullable again)
    
        // update the column from the data in the backup table
        migrationBuilder.Sql(@"
            UPDATE MyOriginalTable
            SET t1.MyNullableColumn = t2.MyNullableColumn
            FROM MyOriginalTable AS t1
            INNER JOIN MyNewBackupTable AS t2
            ON t1.MyId = t2.MyId 
        ");
    
        // remove the backup table
        migrationBuilder.Sql(@"DROP TABLE MyNewBackupTable");
    }
    

    如果要求允许您定义“不归路点”,您也可以在后续迁移之一 (Up) 中删除备份。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-24
      • 2021-05-16
      • 2016-02-04
      • 2016-06-02
      • 2014-07-08
      • 2015-05-11
      相关资源
      最近更新 更多