EF Core сущности TPH с тем же обязательным типом свойства вызывают исключение «Введение ограничения FOREIGN KEY» - PullRequest
2 голосов
/ 19 марта 2019

У меня есть два класса, которые являются производными от одного базового класса и имеют одинаковые обязательные свойства. Они находятся в одной таблице (TPH).

Когда я пытаюсь создать БД, я получаю следующее исключение:

System.Data.SqlClient.SqlException: введение внешнего ключа ограничение 'FK_As_Bs_A2BId' для таблицы 'As' может вызывать циклы или множественные каскадные дорожки. Укажите УДАЛИТЬ НЕТ ДЕЙСТВИЙ или ОБНОВИТЬ НЕТ ДЕЙСТВИЙ, или изменить другие ограничения FOREIGN KEY. Не удалось создать ограничение или индекс. Смотрите предыдущие ошибки.

public class Entity
{
    public long Id { get; set; }
}

public abstract class A : Entity { }

public class A1 : A
{
    [Required]
    public B A1B { get; set; }
}

public class A2 : A
{
    [Required]
    public B A2B { get; set; }
}

public class B : Entity { }

public class MyContext : DbContext
{
    public MyContext(DbContextOptions options) : base(options)
    {
    }

    public DbSet<A> As { get; set; }
    public DbSet<A1> A1s { get; set; }
    public DbSet<A2> A2s { get; set; }
    public DbSet<B> Bs { get; set; }
}

public class CreateDbTests
{
    [Fact]
    public void CreateDb()
    {
        var optionsBuilder = new DbContextOptionsBuilder();

        optionsBuilder.UseSqlServer("YOURCONNECTIONSTRING");
        using (var context = new MyContext(optionsBuilder.Options))
        {
            context.Database.EnsureDeleted();
            context.Database.EnsureCreated();
        }
    }
}

Может кто-нибудь объяснить мне проблему? Я не понимаю Почти думаю, что это ошибка. Проблема возникает только тогда, когда свойство обоих объектов имеет обязательный атрибут, и оба находятся в одной таблице (TBH). Нет проблем, когда A1 и A2 получают свои собственные таблицы (не добавляя DbSet<A>).

1 Ответ

3 голосов
/ 19 марта 2019

Это не ошибка, а ограничение базы данных SqlServer (и некоторых других). Это происходит, когда одна таблица имеет более одного каскадного отношения FK с другой таблицей.

В вашем случае это вызвано TPH, но то же самое произойдет, если у вас есть

public class C : Entity
{
    [Required]
    public B C1B { get; set; }
    [Required]
    public B C2B { get; set; }
}

TPH использует одну таблицу для хранения всех производных сущностей, следовательно, для всех таблиц установлены ограничения на отношения FK.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...