实体框架代码优先迁移 - 因为它不存在(命名约定从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)

查看:152
本文介绍了实体框架代码优先迁移 - 因为它不存在(命名约定从4.3到5.0)无法删除约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以前使用EF 4.3并在升级到5.0,我觉得出来的指数,FK约束和限制的PK都已经有自己的命名约定更改为包括DBO(如PK_Users现已成为PK_dbo.Users)

Was previously using EF 4.3 and upon upgrading to 5.0 I find out the Indexes, FK constraints, and PK constraints all have had their naming conventions changed to include dbo (eg. PK_Users has now become PK_dbo.Users)

现在我随时进行更改模型,它需要改变它拥有这些表,它总是说,它不能删除约束,因为它无法找到它。

Now anytime I make a change to the model and it needs to change a table that has these in it, it always says it can't drop constraint because it can't find it.

我只是希望它这样,当它试图删除一个约束/索引/ KEY它首先检查是否预先5.0命名存在一个,如果是砸,但还是重新创建使用新的5.0命名约定为

I just want it so that when it tries to drop a constraint/index/key it first checks to see if the pre-5.0 naming one exists and if so drop it, but still re-create it using the new 5.0 naming conventions.

的命名约定改变像这样从4.3到5.0:

The naming conventions changed like so from 4.3 to 5.0:

主键/索引

Old: PK_Users                    New: PK_dbo.Users

外键

Old: FK_Users_Roles_Role_Id      New: FK_dbo.Users_dbo.Roles_Role_Id               

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

Note: I CANNOT simply have EF regenerate all the tables, I have production data in this database. I also don't want to have to manually do this for every table using custom migrations.

编辑:我发现了一个类似的问题的How我能阻止实体框架5迁移将DBO。成键名?不过这家伙只是想忽略5.0公约和4.3坚持下去,而且只涉及表重命名。我不想这样做,EF作为后续版本可能导致会影响此代码,仅仅是一个麻烦的路线更多的变化。

I found a similar question How can I stop Entity Framework 5 migrations adding dbo. into key names? but this guy just wanted ignore 5.0 conventions and stick with 4.3, and it only dealt with table renaming. I'd prefer not to do that as subsequent versions of EF may cause more changes that would affect this code and just be a hassle down the line.

我试图做的事情在同样的答案公布:

I tried doing something in the same vein as the answer posted:

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;

    }



但错误依然点击:

However the error still hits:

dbo.Users_dbo.Departments_Department_Id'不是一个制约因素。
无法删除约束。请参阅以前的错误。

dbo.Users_dbo.Departments_Department_Id' is not a constraint. Could not drop constraint. See previous errors.

我真的试图覆盖在每一个成员 CSharpMigrationCodeGenerator 并设置在return语句断点,他们没有击中。因此,它出现在我的自定义生成不知疲倦,不知道我与这些遗漏。

I actually tried override every single member in the CSharpMigrationCodeGenerator and setting a breakpoint on the return statement, and none of them hit. So it appears my custom generator never gets used, not sure what I am missing with that.

推荐答案

我想出的答案,它类似于我挂在我的问题的问题的答案。覆盖 CSharpCodeGenerator 问题只有在使用的自定义的迁移

I figured out the answer and it's similar to the answer in the question I linked to in my question. The problem overriding CSharpCodeGenerator is only used in custom migrations.

要覆盖自动迁移你需要重写 SqlServerMigrationSqlGenerator 类,并调用 SetSqlGenerator()在Migration.Configuration构造:

To override the automatic migrations you need to override the SqlServerMigrationSqlGenerator class and call SetSqlGenerator() in the Migration.Configuration constructor:

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

这篇关于实体框架代码优先迁移 - 因为它不存在(命名约定从4.3到5.0)无法删除约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆