コードの最初の移行を使用してテーブルにnull以外の新しい列を追加すると、デフォルト値が自動的に作成されます。これは、既存の行が新しい列の値を持つ必要があるためです(nullにすることはできません)。それはいいですが、その価値がどこにでも割り当てられた後、私はもうそれを望んでいません。値が常に明示的に挿入されていることを確認したいので、nullableではありません。すべてがデフォルトで ''または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);
}
PROS:ヘルパーメソッドが実装されたら、私はちょうど制約を削除するために、1つの単純な行を追加する必要があります。 CONS:削除するだけでインデックスを作成する必要はないと思われます。
もう1つのアプローチは、生成されたマイグレーションを変更することです。追加するために、それをヌル可能にし、すべての値を更新してからヌル値にしないようにします。
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));
}
長所:単純/クリーナー
CONSだ:一時的に私の制約を変更する必要が(私はこれがトランザクションで実行され、したがって、私たちは中に不良データを許可すべきではないと仮定します)。大きなテーブルで更新が遅くなる可能性があります。
どちらの方法が好ましいですか?それとも私が行方不明になっているより良い方法はありますか?
注:列定義を一度に追加してクリーニングする場合を実証しました。以前の移行からのデフォルトをクリーンアップしているだけの場合、2番目の方法は役に立ちません。
解決策1は、デフォルトの制約を削除するのに役立ちました。ありがとうございました。 – angularsen
これは素晴らしいです –