鉴于以下迁移:
[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中是否有办法处理这种情况?或者什么是最佳实践。
答案 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)
;