使用代碼優先遷移將新的不可爲空列添加到表中時,它會自動爲您創建默認值。這很有意義,因爲現有行需要爲新列創建一個值(因爲它不能爲空)。這很好,但在此之後,我們不再需要它了。它是不可空的,因爲我想確保總是顯式插入一個值。如果一切默認爲''或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);
}
優點:一旦輔助方法來實現,我只需要添加一個簡單的線條,以刪除約束。 CONS:似乎沒有必要創建一個索引來刪除它。
另一種方法是更改生成的遷移,因此我們添加它爲空,更新所有值,然後使其不可空。
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));
}
優點:簡單,似乎/清潔
缺點:必須暫時改變我的約束(我假設這運行在一個事務,因此,我們不應該讓壞的數據)。大桌子上的更新可能會很慢。
哪種方法更可取?還是有更好的方法,我錯過了?
注意:我已經演示了您一次添加和清理列定義的情況。如果您只是清除先前遷移的默認設置,則第二種方法無效。
解決方案1幫助我刪除了默認約束,謝謝。 – angularsen
這真棒 –