Введение ограничения FOREIGN KEY для таблицы 'ImageTag' может привести к возникновению циклов или нескольких каскадных путей - PullRequest
0 голосов
/ 26 декабря 2018

В Entity Framework Core я пытаюсь создать систему с моделями 4 дБ - Image, Tag, ImageTag, User.Изображение и тег - это отношение многие ко многим, которое обеспечивается таблицей ImageTag.Изображения и теги также напрямую связаны с пользователями во взаимосвязи «многие-к-одному» (изображения являются собственностью пользователей, поэтому это обязательное отношение), поэтому при удалении пользователя следует каскадно удалить все изображения, теги и теги изображений, принадлежащие этому.Пользователь.Когда я пытаюсь реализовать это и выполнить Update-Database с приведенным ниже кодом, я получаю сообщение об ошибке:

Введение ограничения FOREIGN KEY 'FK_ImageTag_Tags_TagId' в таблицу 'ImageTag' может вызвать циклы или несколько каскадных путей,Укажите ON DELETE NO ACTION или ON UPDATE NO ACTION, или измените другие ограничения FOREIGN KEY.

После долгих проб и ошибок кажется, что одним из решений проблемы является сделать UserId для Image и Tag обнуляемым.Это изменяет действие ReferentialAction в ограничениях для внешнего ключа в этих таблицах с ReferentialAction.Cascade на ReferentialAction.Restrict.Однако ...

1) Я не совсем уверен, почему это решает проблему, поскольку ошибка относится к ограничению ImageTag, а не к пользовательскому.

2) Я не хочу делать отношения между изображениями / тегами и пользователями необязательными / обнуляемыми.

3) Однако это все-таки решается, в идеале это все равно позволит каскадное удаление при необходимости.

public class Image
{
    public long Id { get; set; }
    public string FileExtension { get; set; }
    public int UserId { get; set; }

    public virtual User User { get; set; }
    public virtual ICollection<ImageTag> ImageTags { get; set; }
}

public class Tag
{
    public long Id { get; set; }
    public string Name { get; set; }
    public int UserId { get; set; }

    public virtual User User { get; set; }
    public virtual ICollection<ImageTag> ImageTags { get; set; }
}

public class ImageTag
{
    public long ImageId { get; set; }
    public long TagId { get; set; }

    public virtual Image Image { get; set; }
    public virtual Tag Tag { get; set; }
}

public class User
{
    public int Id { get; set; }

    public virtual ICollection<Image> Images { get; set; }
    public virtual ICollection<Tag> Tags { get; set; }
}

public class MyDbContext : DbContext
{
    ...

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ImageTag>()
            .HasKey(x => new { x.ImageId, x.TagId });
        modelBuilder.Entity<ImageTag>()
            .HasOne(bc => bc.Image)
            .WithMany(b => b.ImageTags)
            .HasForeignKey(bc => bc.ImageId);
        modelBuilder.Entity<ImageTag>()
            .HasOne(bc => bc.Tag)
            .WithMany(c => c.ImageTags)
            .HasForeignKey(bc => bc.TagId);
    }
}
...