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

Раньше я просто удалял внешний ключ, выполнив:

Delete.ForeignKey("FK_TableName_FieldName").OnTable("TableName");

Как мне сначала проверить, существует ли внешний ключ?

6
noblerare 19 Сен 2018 в 17:57

2 ответа

Лучший ответ

Вот как удалить внешний ключ, если он существует, с помощью FluentMigrator:

if (Schema.Table("TableName").Constraint("FK_TableName_FieldName").Exists())
{
   Delete.ForeignKey("FK_TableName_FieldName").OnTable("TableName");
}
5
Martin D. 19 Июн 2019 в 12:50

На основе этого https://stackoverflow.com/a/17501870/10460456 вы можете использовать функцию Execute.WithConnection, чтобы проверить, внешний ключ существует до его удаления.

    Execute.WithConnection((connection, transaction) =>
    {
        DeleteForeignKeyIfExist(connection, transaction, "yourReferencedTable", "yourTable", "foreignColumnName", "foreignKeyName");
    });

    public bool DeleteForeignKeyIfExist(IDbConnection connection, IDbTransaction transaction, string referenceTable, string table, string foreignKeyColumn, string foreignKeyConstrainName)
    {
        using (var cmd = transaction.Connection.CreateCommand())
        {
            cmd.Transaction = transaction;
            cmd.CommandType = CommandType.Text;

            cmd.CommandText = ForeignKeyExistCommand(referenceTable, foreignKeyColumn);

            bool foreignKeyExist = false;
            using (var reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    // If this code is reached, the foreign key exist
                    foreignKeyExist = true;
                    break;
                }
            }

            if (foreignKeyExist)
            {
                cmd.CommandText = $"ALTER TABLE [{table}] DROP CONSTRAINT [{foreignKeyConstrainName}];";

                cmd.ExecuteNonQuery();
                return true;
            }
        }

        return false;
    }

    private string ForeignKeyExistCommand(string foreignTable, string innerColumn)
    {
        return $"SELECT OBJECT_NAME(f.parent_object_id) TableName, " +
                "COL_NAME(fc.parent_object_id, fc.parent_column_id) ColName " +
                "FROM sys.foreign_keys AS f INNER JOIN sys.foreign_key_columns AS fc " +
                "ON f.OBJECT_ID = fc.constraint_object_id INNER JOIN sys.tables t " +
               $"ON t.OBJECT_ID = fc.referenced_object_id WHERE OBJECT_NAME(f.referenced_object_id) = '{foreignTable}' " +
               $"and COL_NAME(fc.parent_object_id,fc.parent_column_id) = '{innerColumn}'";
    }
1
Estrusco 11 Окт 2018 в 08:37