コード ファースト マイグレーションを使用して新しい null 非許容列をテーブルに追加すると、既定値が自動的に作成されます。既存の行は新しい列の値を持つ必要があるため (null にすることはできないため)、これは理にかなっています。それは問題ありませんが、その値がどこにでも割り当てられた後は、もう必要ありません。値が常に明示的に挿入されるようにしたいので、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);
}
長所: ヘルパー メソッドを実装したら、単純な 1 行を追加して制約を削除するだけです。短所: 削除するためだけにインデックスを作成する必要はないようです。
もう 1 つの方法は、生成された移行を変更することです。そのため、null 許容を追加し、すべての値を更新してから、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));
}
長所: よりシンプル/クリーンに見える
短所: 制約を一時的に変更する必要があります (これはトランザクションで実行されると想定しているため、不正なデータを許可するべきではありません)。大きなテーブルでは、更新が遅くなる場合があります。
どの方法が好ましいですか?または、私が見逃しているより良い方法はありますか?
注: 列定義を一度に追加して削除するケースを示しました。以前の移行からデフォルトをクリーンアップするだけの場合、2 番目の方法は役に立ちません。