Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 首先更改EF5代码中的列默认值_C#_Entity Framework 5_Entity Framework Migrations - Fatal编程技术网

C# 首先更改EF5代码中的列默认值

C# 首先更改EF5代码中的列默认值,c#,entity-framework-5,entity-framework-migrations,C#,Entity Framework 5,Entity Framework Migrations,我试图使用CF为现有数据库构建一个模型。我有一列忘记设置一个正常的默认值。我不想改变初始迁移的纯度,我只是想创建另一个迁移(这就是迁移的目的,对吗?:) 但这会产生列,该列已绑定了默认值。SQL Server错误 如何使用CF迁移更改默认值?或者,如何简单地删除默认值(然后用不同的值重新创建) 编辑: 以下是生成的SQL语句: ALTER TABLE [Config] ADD CONSTRAINT DF_DefaultTaxPerDollar DEFAULT 0.087 FOR [Default

我试图使用CF为现有数据库构建一个模型。我有一列忘记设置一个正常的默认值。我不想改变初始迁移的纯度,我只是想创建另一个迁移(这就是迁移的目的,对吗?:)

但这会产生
列,该列已绑定了默认值。
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()
方法与一些受post启发的复杂Sql结合使用。问题源于这样一个事实:SQLServer使用约束来实现默认值(哦!我多么怀念MySQL!),并为约束生成一个名称。因此,Code First团队无法简单地更改或删除/重新创建默认值。

以下是一个受其启发的解决方案。这不是一种优雅的方法,但对我来说很有效


        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不存在且不起作用时才重新创建UDF。我想每次重新创建它都会更加健壮

删除由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);
    }

Guid用于生成唯一的变量名,以防在一次迁移中删除多个约束。

您能发布生成的SQL吗?是的,这是我的观点。我希望迁移只添加约束,而不检查/删除现有约束。我认为这可能被认为是一个bug。你能提供你的解决方案作为答案吗?可以-只要我确定:)我很确定这会起作用,但由于实际的SQL是由AlterColumnOperation对象构建的,然后一次发送到服务器,我的自定义SQL必须很好地处理所有生成的SQL,事实证明这有点棘手。当我让它工作时将发布。仅供参考,这应该在E6中固定(请参见)+1,但是
ALTER TABLE[{1}]…
中的方括号应该被删除。例如,在调用
DropDefaultConstraint(“Sales.Orders”,…)
时,它们会导致架构限定表名出错。如果我的containtname包含字符“.”,则会导致错误。所以我把这一行“EXECUTE('ALTER TABLE{1}DROP CONSTRAINT'+{0})”,改为“EXECUTE('ALTER TABLE{1}DROP CONSTRAINT['+{0}+'])”,行得通。@heavenwing只是想感谢您的提醒,它帮助我在代码中解决了这个问题。
    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));