使用代码优先迁移将新的不可为空列添加到表中时,它会自动为您创建默认值。这很有意义,因为现有行需要为新列创建一个值(因为它不能为空)。这很好,但在此之后,我们不再需要它了。它是不可空的,因为我想确保总是显式插入一个值。如果一切默认为''或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
这真棒 –