Подтвердить что ты не робот

Entity Framework Code-First Migrations - не может отказаться от ограничения, поскольку он не существует (соглашение об именах от 4.3 до 5.0)

Ранее использовал EF 4.3 и при обновлении до 5.0 я обнаружил, что индексы, ограничения FK и ограничения PK у всех были изменены их соглашения об именах, включив dbo (например, PK_Users теперь стали PK_dbo.Users)

Теперь, когда я вношу изменения в модель, и мне нужно изменить таблицу, в которой есть это, он всегда говорит, что не может отказаться от ограничения, потому что не может ее найти.

Я просто хочу, чтобы, когда он пытается сбросить ограничение /index/key, он сначала проверяет, существует ли именование pre-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 регенерировать все таблицы, у меня есть производственные данные в этой базе данных. Я также не хочу, чтобы вручную делать это для каждой таблицы, используя пользовательские миграции.

Изменить: я нашел аналогичный вопрос Как остановить миграцию Entity Framework 5 с добавлением dbo. в имена ключевых слов?, но этот парень просто хотел проигнорировать 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, и ни один из них не попал. Таким образом, кажется, что мой пользовательский генератор никогда не используется, не уверен, что мне не хватает с этим.

4b9b3361

Ответ 1

Я понял ответ, и это похоже на ответ в вопросе, который я связал в своем вопросе. Проблема переопределения CSharpCodeGenerator используется только в пользовательских миграциях.

Чтобы переопределить автоматические миграции, вам необходимо переопределить класс SqlServerMigrationSqlGenerator и вызвать SetSqlGenerator() в конструкторе Migration.Configuration:

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