FluentMigrator откат до не столбце значения null?


Учитывая следующую миграцию:

[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();
    }
}

Мигратор изменяет столбец и делает его nullable, а при откате он делает обратное и снова делает его nullable.

Предположим, что данные были добавлены в foo с момента миграции; теперь в столбце bar есть строки с null.

Если он откатится, то операция завершится неудачей, есть ли в fluentmigrator способ справиться с этим сценарием? Или то, что является лучшей практикой.

3 10

3 ответа:

Короткий ответ состоит в том, чтобы установить значение по умолчанию для всех столбцов, которые имеют значение null. Вы можете сделать это только с sql, используя Execute.выражение SQL. Это должно быть до Альтера.Табличное выражение.

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

Длинный ответ заключается в том, что это большая работа, чтобы всегда гарантировать, что вы можете откатить миграцию, и вы уверены, что вам это нужно сделать?

Например, если действие вверх заключается в создании таблицы, а действие вниз-в ее удалении, следует ли сохранять данные во временной таблице чтобы она не исчезла? В большинстве случаев действие "вниз" используется при развертывании в тестовых средах или при откате неудачного развертывания, и довольно редко можно откатить миграцию после ее развертывания.

Вот альтернативный способ выполнения миграции, который не требует прямого выполнения SQL.

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

Старая тема, но вы можете сделать это, чтобы дать существующим строкам (новое) значение:

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