簡體   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