首先在代码中添加新列后删除默认约束

问题描述 投票:27回答:2

使用代码优先迁移将新的非空列添加到表中时,它将自动为您创建一个默认值。这是有道理的,因为现有行需要为新列具有一个值(因为它不能为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);
}

PROS:实现了辅助方法后,我只需要添加一条简单的行即可删除约束。缺点:似乎不必创建索引就可以删除它。

另一种方法是更改​​所生成的迁移,因此我们将其添加为可为空,更新所有值,然后使其不可为空。

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));
}

PROS:似乎更简单/更干净

CONS:必须临时更改约束(我假设此约束在事务中运行,因此我们不应该允许输入不良数据)。在大表上更新可能会很慢。

哪种方法更可取?还是我想念一种更好的方法?

注:我已经演示了一次性添加和清除列定义的情况。如果您只是清理以前的迁移中的默认值,则第二种方法没有帮助。

tsql ef-migrations
2个回答
12
投票
即使这种方法仍然存在问题,问题在于,除了第二种方法之外,几乎没有其他选择。在我看来,用默认值更新可能较大的表的开销似乎比创建和立即删除默认约束的开销更大。

不过,我可能会考虑进行一些修改:我可能会在SQL中创建约束,以避免大惊小怪地查找引擎分配的默认名称,就像这样:

Sql("ALTER TABLE tablename ADD columnname type NOT NULL CONSTRAINT DF_tablename_columnname DEFAULT defaultvalue");

(可以重写以使用辅助功能。)

然后,删除约束就像执行单个ALTER TABLE语句一样简单:

Sql("ALTER TABLE tablename DROP CONSTRAINT DF_tablename_columnname");

(再次,可以在此处轻松使用辅助函数。)

但是,在我看来,所有人可能都是T-SQL开发人员,胜于C#。因此,您很可能会使用与所发布示例类似的代码。    

0
投票
删除下面的默认列值约束---->ALTER TABLE [dbo]。[附件]为[DocumentUniqueId]添加默认('00000000-0000-0000-0000-000000000000')

首先应用此代码C#---->

受保护的覆盖无效Up(MigrationBuilder migrationBuilder) { migrationBuilder.AlterColumn( 名称:“ ColumnName”, 模式:“ dbo”, 表格:“ TableName”, 类型:“ uniqueidentifier”, 可为空:false,

defaultValueSql:空,

oldClrType:typeof(Guid), oldType:“ uniqueidentifier”); }

我一无所获,所以我将其发布以帮助其他人,这对数据库清理很有帮助。

-vaya
© www.soinside.com 2019 - 2024. All rights reserved.