C# 由于默认值约束,代码首次迁移失败

C# 由于默认值约束,代码首次迁移失败,c#,entity-framework,ef-code-first,entity-framework-migrations,C#,Entity Framework,Ef Code First,Entity Framework Migrations,更改实体上属性的类型时出现问题,已创建默认约束,但EF在更改列时未删除该约束,因此更新数据库失败 该实体以前具有DateTime属性 public DateTime ImportDate { get; set; } 它的迁移包含在它的Up()方法中 AddColumn("dbo.Table", "ImportDate", c => c.DateTime(nullable: false)); 但是,它还创建了一个默认约束 ALTER TABLE [dbo].[Table] ADD DE

更改实体上属性的类型时出现问题,已创建默认约束,但EF在更改列时未删除该约束,因此更新数据库失败

该实体以前具有DateTime属性

public DateTime ImportDate { get; set; }
它的迁移包含在它的
Up()
方法中

AddColumn("dbo.Table", "ImportDate", c => c.DateTime(nullable: false));
但是,它还创建了一个默认约束

ALTER TABLE [dbo].[Table] ADD  DEFAULT ('1900-01-01T00:00:00.000') FOR [ImportDate]
ImportDate正在更改为DateTimeOffset

public DateTimeOffset ImportDate { get; set; }
由此产生的迁移有一个列

AlterColumn("dbo.Table", "ImportDate", c => c.DateTimeOffset(nullable: false, precision: 7));
但是,这会失败,因为存在默认约束

我能想到的唯一方法是使用带有DROP约束的
Sql(…)
,然而,该约束的名称似乎是随机的
DF_uuuutable\uuuu Import\uuu 5441852A
,因此硬编码的Sql不会在任何地方都起作用


想法?

您可以创建一个扩展并在生成的迁移中使用它:

 internal static class MigrationExtensions
    {
        public static void DeleteDefaultContraint(this IDbMigration migration, string tableName, string colName, bool suppressTransaction = false)
        {
            var sql = new SqlOperation(String.Format(@"DECLARE @SQL varchar(1000)
                SET @SQL='ALTER TABLE {0} DROP CONSTRAINT ['+(SELECT name
                FROM sys.default_constraints
                WHERE parent_object_id = object_id('{0}')
                AND col_name(parent_object_id, parent_column_id) = '{1}')+']';
                PRINT @SQL;
                EXEC(@SQL);", tableName, colName)) { SuppressTransaction = suppressTransaction };
            migration.AddOperation(sql);
        }
    }
像这样使用

this.DeleteDefaultContraint("dbo.Table", "ImportDate");

从这篇文章:

更好的方法是永远解决这个问题

您可以从System.Data.Entity.SqlServer命名空间实现从SqlServerMigrationSqlGenerator派生的自定义sql生成器类:

using System.Data.Entity.Migrations.Model;
using System.Data.Entity.SqlServer;

namespace System.Data.Entity.Migrations.Sql{
    internal class FixedSqlServerMigrationSqlGenerator : SqlServerMigrationSqlGenerator {
        protected override void Generate(AlterColumnOperation alterColumnOperation){
            ColumnModel column = alterColumnOperation.Column;
            var sql = String.Format(@"DECLARE @ConstraintName varchar(1000);
            DECLARE @sql varchar(1000);
            SELECT @ConstraintName = name   FROM sys.default_constraints
                WHERE parent_object_id = object_id('{0}')
                AND col_name(parent_object_id, parent_column_id) = '{1}';
            IF(@ConstraintName is NOT Null)
                BEGIN
                set @sql='ALTER TABLE {0} DROP CONSTRAINT [' + @ConstraintName+ ']';
            exec(@sql);
            END", alterColumnOperation.Table, column.Name);
                this.Statement(sql);
            base.Generate(alterColumnOperation);
            return;
        }
        protected override void Generate(DropColumnOperation dropColumnOperation){
            var sql = String.Format(@"DECLARE @SQL varchar(1000)
                SET @SQL='ALTER TABLE {0} DROP CONSTRAINT [' + (SELECT name
                    FROM sys.default_constraints
                    WHERE parent_object_id = object_id('{0}')
                    AND col_name(parent_object_id, parent_column_id) = '{1}') + ']';
            PRINT @SQL;
                EXEC(@SQL); ", dropColumnOperation.Table, dropColumnOperation.Name);

                    this.Statement(sql);
            base.Generate(dropColumnOperation);
        }
    }
}
并设置此配置:

internal sealed class Configuration : DbMigrationsConfiguration<MyDbContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = true;

        SetSqlGenerator("System.Data.SqlClient", new FixedSqlServerMigrationSqlGenerator ());
    }
    ...
}
内部密封类配置:dbmigtorinsconfiguration
{
公共配置()
{
AutomaticMiggerationsEnabled=真;
SetSqlGenerator(“System.Data.SqlClient”,新的FixedSqlServerMigrationSqlGenerator());
}
...
}

这以一种相当复杂的方式解决了它,需要一些手工编码,如果这对我们也有帮助的话,请参见。