FluentMigrator回滚到Not Nullable列?

时间:2013-06-10 18:34:36

标签: c# nullable rollback fluent-migrator

鉴于以下迁移:

[Migration(1)]
public class Mig001 : Migration
{
    public override void Up()
    {
        Alter.Table("foo").AlterColumn("bar").AsInt32().Nullable();
    }

    public override void Down()
    {
        Alter.Table("foo").AlterColumn("bar").AsInt32().NotNullable();
    }
}

迁移器更改一个列并使其可以为空,并且在回滚时它执行相反的操作并使其不再为空。

让我们说自迁移以来,数据已添加到foo;现在,bar列中存在空行。

如果它被回滚,那么操作将失败,在fluentmigrator中是否有办法处理这种情况?或者什么是最佳实践。

3 个答案:

答案 0 :(得分:10)

简短的回答是为具有可空值的所有列设置默认值。您可以使用Execute.Sql表达式使用sql执行此操作。这应该在Alter.Table表达式之前。

public override void Down()
{
    Execute.Sql("update foo set bar = 0 where bar is null");
    Alter.Table("foo").AlterColumn("bar").AsInt32().NotNullable();
}

长期的答案是,要始终确保您可以回滚迁移并且确定需要执行此操作,需要做很多工作吗?

例如,如果up操作是创建一个表而down操作是要删除它,那么你应该将数据保存在临时表中以使它不会消失吗?对于大多数用例,在测试环境中部署或回滚失败的部署时会使用向下操作,并且在部署之后很少会回滚迁移。

答案 1 :(得分:8)

以下是执行迁移的另一种方法,不需要直接执行SQL。

public override void Down()
{
    Update.Table("foo").Set(new { bar = 0 }).Where(new { bar = (int?) null });
    Alter.Table("foo").AlterColumn("bar").AsInt32().NotNullable();
}

答案 2 :(得分:0)

旧主题,但您可以执行此操作以向现有行提供(新)值:

            migration.Alter.Table("foo")
                .AlterColumn("bar")
                .AsDateTime()
                .NotNullable()
                .SetExistingRowsTo(DateTime.UtcNow)
            ;