c# - Entity Framework 代码优先迁移 - 无法删除约束,因为它不存在(从 4.3 到 5.0 的命名约定)

标签 c# entity-framework ef-code-first entity-framework-5 entity-framework-migrations

之前使用的是 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 重新生成所有表,我在这个数据库中有生产数据。我也不想使用自定义迁移为每个表手动执行此操作。

编辑:我发现了一个类似的问题How can I stop Entity Framework 5 migrations adding dbo. into key names?但是这个人只想忽略 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' is not a constraint. Could not drop constraint. See previous errors.

我实际上尝试覆盖 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());
    }

关于c# - Entity Framework 代码优先迁移 - 无法删除约束,因为它不存在(从 4.3 到 5.0 的命名约定),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17241594/

相关文章:

c# - InvokeOnMainThread 不适用于 `method group`

c# - 允许空值时如何将 nvarchar(x) 读入 String?

c# - 使用 Entity Framework 插入时有条件地设置 Identity 字段

entity-framework - Entity Framework 5 Code First - 添加用户权限作为播种过程的一部分

entity-framework - EF - 如何使用流畅的 EntityTypeConfiguration API 定义正则表达式属性?

没有 mdi 父级的 C# 级联表单?

c# - + intCounter在Visual Studio中生成错误CS0201

.net - 使用.NET 4.5连接到SQL Server Azure时发生握手异常

c# - 在 LINQ 语句中调用标量函数(无需 EDMX)

asp.net-mvc-3 - ASP.NET MVC 3 一对多表单