Удаление ограничения по умолчанию после добавления нового столбца в код сначала

При добавлении нового столбца, не допускающего значения NULL, в таблицу с помощью первой миграции кода автоматически создается значение по умолчанию. Это имеет смысл, поскольку существующие строки должны иметь значение для нового столбца (поскольку оно не может быть нулевым). Это нормально, но после того, как это значение будет присвоено везде, оно мне больше не нужно. Это значение не может быть обнулено, потому что я хочу убедиться, что значение всегда вставляется явно. Если по умолчанию все равно '' или 0, тогда у меня будут волшебные строки. Так или иначе, я могу найти решение, которое меня не в восторге, но оно работает.

После добавления столбца я удаляю ограничение по умолчанию.

public override void Up()
{
    AddColumn("dbo.SomeTable", "NewColumn", c => c.Int(nullable: false));
    Sql(Helpers.DropDefaultConstraint("dbo.SomeTable", "NewColumn"));
}

...

public static string DropDefaultConstraint(string table, string column)
{
    return string.Format(@"
        DECLARE @name sysname

        SELECT @name = dc.name
        FROM sys.columns c
        JOIN sys.default_constraints dc ON dc.object_id = c.default_object_id
        WHERE c.object_id = OBJECT_ID('{0}')
        AND c.name = '{1}'

        IF @name IS NOT NULL
            EXECUTE ('ALTER TABLE {0} DROP CONSTRAINT ' + @name)
        ",
        table, column);
}

ЗА: После реализации вспомогательного метода мне просто нужно добавить одну простую строку, чтобы удалить ограничение. ПРОТИВ: кажется ненужным создавать индекс только для его удаления.

Другим подходом может быть изменение сгенерированной миграции, поэтому мы добавим, что она допускает значение NULL, обновим все значения, а затем сделаем ее необнуляемой.

public override void Up()
{
    AddColumn("dbo.SomeTable", "NewColumn", c => c.Int());
    Sql("UPDATE dbo.SomeTableSET NewColumn= 1");
    AlterColumn("dbo.SomeTable", "NewColumn", c => c.Int(nullable: false));
}

ЗА: кажется проще/чище

ПРОТИВ: Приходится временно изменять мои ограничения (я предполагаю, что это выполняется в транзакции, и поэтому мы не должны допускать неверные данные). Обновление может быть медленным на больших таблицах.

Какой метод предпочтительнее? Или есть лучший способ, который мне не хватает?

Примечание. Я продемонстрировал случай, когда вы добавляете и очищаете определения столбцов за один раз. Если вы просто очищаете значения по умолчанию от предыдущих миграций, второй подход бесполезен.

26
задан Dan Friedman 3 June 2012 в 09:00
поделиться