C# FluentMigrator是否回滚到不可为空的列?
考虑到以下迁移:C# FluentMigrator是否回滚到不可为空的列?,c#,nullable,rollback,fluent-migrator,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
[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();
}
}
迁移器更改列并使其可为null,在回滚时,它执行相反的操作并使其再次不可为null
假设自迁移以来,数据已添加到foo
;现在在bar
列中有空的行
如果回滚,则操作将失败,fluentmigrator中是否有任何方法可以处理此场景?或者最佳做法是什么。简单的答案是为所有具有可空值的列设置默认值。您可以使用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操作,并且很少在部署迁移后回滚迁移。这里有一种执行迁移的替代方法,不需要直接执行SQL
public override void Down()
{
Update.Table("foo").Set(new { bar = 0 }).Where(new { bar = (int?) null });
Alter.Table("foo").AlterColumn("bar").AsInt32().NotNullable();
}
旧主题,但您可以这样做为现有行提供一个(新)值:
我猜如果
bar
是一个外键列,那就行不通了?Down方法可以留空吗?如果它是外键列,那么sql查询必须更智能一些,并找到要设置的正确值。或者您是否有可以作为默认值使用的外键值?很遗憾,没有默认的外键值。”“0”将指向父表中不存在的记录。是否可以编写sql查询来查找正确的父记录?如果是,则可以使用Execute.Sql运行它。如果不是,那么我想您必须手动执行。但是setExistingRows是否会添加其中bar为null的条件?或者它使用所有行…SetExistingRowsTo将设置所有现有行,因为它的目的是使添加没有默认值的非空列变得简单。我们需要一个额外的助手,比如SetNullRowsTo或类似的东西,但是说实话,在将现有列从null更新为非null的情况下,我认为使用Lucas建议的方法是最好的方法,并且不会导致用虚假的助手方法阻塞api。
migration.Alter.Table("foo")
.AlterColumn("bar")
.AsDateTime()
.NotNullable()
.SetExistingRowsTo(DateTime.UtcNow)
;