Hir*_*ind 11 c# ef-migrations entity-framework-5
我正在尝试使用CF为现有数据库构建模型.我有一个专栏,我忘了设置一个合理的默认值.而不是通过改变它来破坏初始迁移的纯度,我只是想我创建另一个迁移(这是迁移的目的,对吧?:)
public override void Up()
{
    AlterColumn("Config", "DefaultTaxPerDollar", c => c.Decimal(nullable: false, precision: 19, scale: 5, defaultValue: 0.087m));
}
public override void Down()
{
    AlterColumn("Config", "DefaultTaxPerDollar", c => c.Decimal(nullable: false, precision: 19, scale: 5, defaultValue: 0.0m));
}
但是这会Column already has a DEFAULT bound to it.从SQL Server 产生错误.  
如何使用CF迁移更改默认值?或者,如何简单地删除默认值(然后使用不同的值重新创建它)?
编辑:
这是生成的SQL:
ALTER TABLE [Config] ADD CONSTRAINT DF_DefaultTaxPerDollar DEFAULT 0.087 FOR [DefaultTaxPerDollar]
ALTER TABLE [Config] ALTER COLUMN [DefaultTaxPerDollar] [decimal](19, 5) NOT NULL
我想我可能已经找到了一个解决方案,将这个Sql()方法与这个帖子启发的一些复杂的SQL 一起使用.问题源于这样一个事实:SQL Server使用约束来实现默认值(OH!我多么想念MySQL!),并为约束生成了名称.因此,Code First团队无法轻易地更改或删除/重新创建默认值.
Mik*_*ike 13
删除受Entity Framework for SQL Server生成的反向迁移启发的默认约束
    public static void DropDefaultConstraint(string tableName, string columnName, Action<string> executeSQL)
    {
        string constraintVariableName = string.Format("@constraint_{0}", Guid.NewGuid().ToString("N"));
        string sql = string.Format(@"
            DECLARE {0} nvarchar(128)
            SELECT {0} = name
            FROM sys.default_constraints
            WHERE parent_object_id = object_id(N'{1}')
            AND col_name(parent_object_id, parent_column_id) = '{2}';
            IF {0} IS NOT NULL
                EXECUTE('ALTER TABLE {1} DROP CONSTRAINT ' + {0})",
            constraintVariableName,
            tableName,
            columnName);
        executeSQL(sql);
    }
它略短,但使用方法相同.
DropDefaultConstraint(TableName, "DefaultTaxPerDollar", q => Sql(q));
Guid用于创建唯一的变量名称,以防您在一次迁移中删除多个约束.
这是一个灵感来自这篇文章的解决方案.这不是一个优雅的方法,但它适用于我.
        public static void DropDefaultConstraint(string tableName, string columnName, Action executeSQL)
        {
            // Execute query that drops the UDF that finds the default constraint name
            var query = @"
                    -- recreate UDF 
                    if object_id('[dbo].[GetDefaultConstraintName]') is not null
                    begin 
                        drop function [dbo].[GetDefaultConstraintName]
                    end
                ";
            executeSQL(query);
            // Execute query that (re)creates UDF that finds the default constraint name
            query = @"
                    create function [dbo].[GetDefaultConstraintName] (
                        @TableName varchar(max),
                        @ColumnName varchar(max))
                    returns varchar(max)
                    as
                    begin
                        -- Returns the name of the default constraint for a column
                        declare @Command varchar(max)
                        select
                            @Command = d.name
                        from
                            ((
                            sys.tables t join
                            sys.default_constraints d
                                on
                                    d.parent_object_id = t.object_id) join
                            sys.columns c
                                on
                                    c.object_id = t.object_id and
                                    c.column_id = d.parent_column_id)
                        where
                            t.name = @TableName and
                            c.name = @ColumnName
                        return @Command
                    end
                ";
            executeSQL(query);
            // Execute query that actually drops the constraint
            query = string.Format(@"
                    -- Use UDF to find constraint name
                    DECLARE @Constraint_Name VARCHAR(100)
                    SET @Constraint_Name = [dbo].GetDefaultConstraintName('{0}','{1}')
                    if LEN(@Constraint_Name) > 0 
                    BEGIN
                        DECLARE @query VARCHAR(300)
                        SET @query = 'ALTER TABLE {0} DROP CONSTRAINT ' + @Constraint_Name
                        execute(@query)
                    END", tableName, columnName);
            executeSQL(query);
        }
在迁移中,您可以这样调用它:
DropDefaultConstraint(TableName, "DefaultTaxPerDollar", q => Sql(q));
使用lamba的原因是因为你必须进行三次不同的调用Sql().我无法将其作为一个长查询工作 - GO在许多不同的地方尝试了许多关键字组合.我还尝试在第一个查询上反转逻辑,以便只有UDF不存在才会重新创建,并且它不起作用.我想每次重建它都会更加强大.