Изменение соглашения об именовании ограничений внешних ключей

У нас есть собственное внешнее соглашение об именах объектов, и мне нужно изменить соглашение об именах для автоматически сгенерированных ограничений внешнего ключа. Теперь это выглядит так: FK_dbo.City_dbo.CityType_City_CityTypeId, но я бы хотел, чтобы его называли City_FKC_CityType.

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

Я нашел некоторую информацию о "Пользовательских кодовых первых соглашениях", и мне интересно, могу ли я изменить имя ограничения с помощью этого или если есть какие-либо методы его реализации?

Другой вариант - загрузить исходный код EF, внести изменения и использовать его, но это в случае чрезвычайной ситуации.

В качестве дополнительной заметки я также хотел бы изменить соглашение об именах первичного ключа.

Ответ 1

Вы можете реализовать пользовательский класс генератора sql, полученный из SqlServerMigrationSqlGenerator из System.Data.Entity.SqlServer пространства имен:

public class CustomSqlGenerator : SqlServerMigrationSqlGenerator
{
    protected override void Generate(AddForeignKeyOperation addForeignKeyOperation)
    {
        addForeignKeyOperation.Name = getFkName(addForeignKeyOperation.PrincipalTable,
            addForeignKeyOperation.DependentTable, addForeignKeyOperation.DependentColumns.ToArray());
        base.Generate(addForeignKeyOperation);
    }

    protected override void Generate(DropForeignKeyOperation dropForeignKeyOperation)
    {
        dropForeignKeyOperation.Name = getFkName(dropForeignKeyOperation.PrincipalTable,
            dropForeignKeyOperation.DependentTable, dropForeignKeyOperation.DependentColumns.ToArray());
        base.Generate(dropForeignKeyOperation);
    }

    private static string getFkName(string primaryKeyTable, string foreignKeyTable, params string[] foreignTableFields)
    {
        // Return any format you need
    }
}

Затем вам необходимо зарегистрировать генератор в DbContext с помощью DbConfiguration:

public class CustomDbConfiguration : DbConfiguration
{
    public CustomDbConfiguration()
    {
        SetMigrationSqlGenerator(SqlProviderServices.ProviderInvariantName,
            () => new CustomSqlGenerator());
    }
}

И DbConfigurationTypeAttribute:

[DbConfigurationType(typeof(CustomDbConfiguration))]
public class YourEntities : DbContext

UPDATE: если вы хотите изменить имя первичного ключа, вам необходимо переопределить следующие методы Generate:

protected override void Generate(CreateTableOperation createTableOperation) 
{
    createTableOperation.PrimaryKey.Name = getPkName(createTableOperation.Name);
    base.Generate(createTableOperation);
}

protected override void Generate(AddPrimaryKeyOperation addPrimaryKeyOperation)
{
    addPrimaryKeyOperation.Name = getPkName(addPrimaryKeyOperation.Table);
    base.Generate(addPrimaryKeyOperation);
}

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