Changing column default values in EF5 Code First

后端 未结 2 1771
时光取名叫无心
时光取名叫无心 2020-12-17 18:56

I\'m trying to use CF to build a model for an existing database. I have a column in which I forgot to set a sane default value. And rather than compromise the purity of th

2条回答
  •  余生分开走
    2020-12-17 19:42

    Here's a solution that was inspired by this post. It's not exactly an elegant method, but it works for me.

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

    And in your migration, you can call it like this:

    DropDefaultConstraint(TableName, "DefaultTaxPerDollar", q => Sql(q));
    

    The reason for using the lamba is because you have to make three distinct calls to Sql(). I was never able to get this to work as one long query - tried many combinations of the keyword GO in many different places. I also tried reversing the logic on the first query so that the UDF only gets recreated if it does not exist, and it didn't work. I suppose recreating it every time is more robust anyway.

提交回复
热议问题