14

鉴于以下迁移:

[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 有没有办法处理这种情况?或者什么是最佳实践。

4

3 回答 3

12

简短的回答是为所有具有可为空值的列设置默认值。您可以使用 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();
}

长答案是,始终确保可以回滚迁移需要大量工作,并且您确定需要这样做吗?

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

于 2013-06-11T15:02:55.897 回答
10

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

public override void Down()
{
    Update.Table("foo").Set(new { bar = 0 }).Where(new { bar = (int?) null });
    Alter.Table("foo").AlterColumn("bar").AsInt32().NotNullable();
}
于 2013-08-09T13:20:37.820 回答
2

旧主题,但您可以这样做给现有行一个(新)值:

            migration.Alter.Table("foo")
                .AlterColumn("bar")
                .AsDateTime()
                .NotNullable()
                .SetExistingRowsTo(DateTime.UtcNow)
            ;
于 2016-01-13T15:22:53.547 回答