繁体   English   中英

实体框架代码优先迁移 - 不能删除约束,因为它不存在(命名约定从4.3到5.0)

[英]Entity Framework Code-First Migrations - Cannot drop constraint because it doesn't exist (naming convention from 4.3 to 5.0)

以前使用EF 4.3并在升级到5.0时我发现索引,FK约束和PK约束都将其命名约定更改为包含dbo(例如PK_Users现在变为PK_dbo.Users)

现在,每当我对模型进行更改并且需要更改包含这些内容的表时,它总是说它不能删除约束,因为它无法找到它。

我只是想要它,以便当它试图删除约束/索引/键时,它首先检查5.0之前的命名是否存在,如果是,则删除它,但仍然使用新的5.0命名约定重新创建它。

命名约定从4.3更改为5.0:

主键/索引

Old: PK_Users                    New: PK_dbo.Users

外键

Old: FK_Users_Roles_Role_Id      New: FK_dbo.Users_dbo.Roles_Role_Id               

注意:我不能简单地让EF重新生成所有表,我在这个数据库中有生产数据。 我也不想为每个使用自定义迁移的表手动执行此操作。

编辑:我发现了一个类似的问题如何停止添加dbo的Entity Framework 5迁移。 成为关键名称? 但是这个家伙只是想忽略5.0惯例并坚持使用4.3,它只处理表重命名。 我不希望这样做,因为后续版本的EF可能会导致更多的更改,这些更改会影响此代码并且只是麻烦。

我试着按照发布​​的答案做同样的事情:

public class CodeMigrator : CSharpMigrationCodeGenerator
{
    protected override void Generate(
        DropIndexOperation dropIndexOperation, IndentedTextWriter writer)
    {
        dropIndexOperation.Name = StripDbo(dropIndexOperation.Name);
        base.Generate(dropIndexOperation, writer);
    }

    protected override void Generate(DropForeignKeyOperation dropForeignKeyOperation, IndentedTextWriter writer)
    {
        dropForeignKeyOperation.Name = StripDbo(dropForeignKeyOperation.Name);
        base.Generate(dropForeignKeyOperation, writer);
    }

    protected override void Generate(DropPrimaryKeyOperation dropPrimaryKeyOperation, IndentedTextWriter writer)
    {
        dropPrimaryKeyOperation.Name = StripDbo(dropPrimaryKeyOperation.Name);
        base.Generate(dropPrimaryKeyOperation, writer);
    }

    // TODO: Override other Generate overloads that involve table names

    private string StripDbo(string name)
    {
        return name.Replace("dbo.", "");
    }
}

并将其添加到配置:

public Configuration()
    {
        CodeGenerator = new CodeMigrator();
        AutomaticMigrationsEnabled = true;
        AutomaticMigrationDataLossAllowed = false;

    }

但是错误仍然存​​在:

dbo.Users_dbo.Departments_Department_Id'不是约束。 无法删除约束。 查看以前的错误。

我实际上尝试覆盖CSharpMigrationCodeGenerator中的每个成员并在return语句上设置断点,但没有一个成功。 所以看来我的自定义生成器永远不会被使用,不知道我错过了什么。

我找到了答案,它与我在问题中链接的问题中的答案类似。 覆盖CSharpCodeGenerator的问题仅用于自定义迁移

要覆盖自动迁移,您需要覆盖SqlServerMigrationSqlGenerator类并在Migration.Configuration构造函数中调用SetSqlGenerator()

public class SqlMigrator : SqlServerMigrationSqlGenerator
{
    protected override void Generate(DropForeignKeyOperation dropForeignKeyOperation)
    {
        dropForeignKeyOperation.Name = StripDbo(dropForeignKeyOperation.Name);
        base.Generate(dropForeignKeyOperation);
    }

    protected override void Generate(DropIndexOperation dropIndexOperation)
    {
        dropIndexOperation.Name = StripDbo(dropIndexOperation.Name);
        base.Generate(dropIndexOperation);
    }

    protected override void Generate(DropPrimaryKeyOperation dropPrimaryKeyOperation)
    {
        dropPrimaryKeyOperation.Name = StripDbo(dropPrimaryKeyOperation.Name);
        base.Generate(dropPrimaryKeyOperation);
    }

    private string StripDbo(string name)
    {
        return name.Replace("dbo.", "");
    }
}

和迁移配置:

public Configuration()
    {
        AutomaticMigrationsEnabled = true;
        AutomaticMigrationDataLossAllowed = false;
        SetSqlGenerator("System.Data.SqlClient", new SqlMigrator());
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM