EF Core中循环和多个级联路径的实际工作方式

时间:2019-03-14 13:46:06

标签: sql-server entity-framework-core

有人可以向我解释为什么出现此错误。

  

在上引入FOREIGN KEY约束'FK_CommentMention_User_UserId'   表“ CommentMention”可能会导致循环或多个级联路径。

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

    [Required]
    public string Message { get; set; }

    public DateTimeOffset CreationDate { get; set; } = DateTimeOffset.UtcNow;

    public int? CandidatureId { get; set; }
    public Candidature Candidature { get; set; }

    public int AuthorId { get; set; }
    public User Author { get; set; }

    public IList<CommentMention> MentionedUsers { get; set; } = new List<CommentMention>();
}

public class CommentMention
{
    public int CommentId { get; set; }
    public Comment Comment{ get; set; }

    public int UserId { get; set; } // That's the foreign property which cause the error
    public User User { get; set; }
}

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

    [Required]
    public string Email { get; set; }

    [Required]
    public string PasswordHash { get; set; }

    [Required]
    public string FirstName { get; set; }

    [Required]
    public string MiddleName { get; set; }

    [Required]
    public string LastName { get; set; }

    [Required]
    public string Phone { get; set; }

    [Required]
    public string Role { get; set; }

    public bool Disabled { get; set; } = false;

    public DateTimeOffset CreationDate { get; set; } = DateTimeOffset.UtcNow;

    public int? CompanyId { get; set; }
    public Company Company { get; set; }

    public int? CreatedByUserId { get; set; }
    public User CreatedByUser { get; set; }

    public IList<User> SubUsers { get; set; } = new List<User>();

    [InverseProperty("CreatedByUser")]
    public IList<Candidature> CreatedCandidatures { get; set; } = new List<Candidature>();

    [InverseProperty("Lawyer")]
    public IList<Candidature> LawyerCandidatures { get; set; } = new List<Candidature>();

    [InverseProperty("Agent")]
    public IList<Candidature> AgentCandidatures { get; set; } = new List<Candidature>();

    public IList<UserDocument> Documents { get; set; } = new List<UserDocument>();

    public IList<Comment> Comments { get; set; } = new List<Comment>();

    public IList<Event> Events { get; set; } = new List<Event>();

    public IList<Reminder> Reminders { get; set; } = new List<Reminder>();

    public IList<CommentMention> Mentions { get; set; } = new List<CommentMention>();

    [InverseProperty("Owner")]
    public IList<Notification> Notifications { get; set; } = new List<Notification>();

    [NotMapped]
    public string FullName => this.FirstName + " " + this.LastName;
}

实际上,问题不在于如何解决它,因为我已经知道了增加受限删除行为的方法。

modelBuilder.Entity<CommentMention>()
    .HasOne(x => x.User)
    .WithMany(x => x.Mentions)
    .HasForeignKey(x => x.UserId)
    .OnDelete(DeleteBehavior.Restrict);

真正的问题是那些“循环或多个级联路径”在哪里,因为我看不到哪个会导致该错误。

让我们介绍可能的删除变体:

  1. CommentMention中的一条记录被删除:没有级联删除,因为 那是子实体/依存实体。
  2. 注释中的记录已删除:级联删除已删除的记录 在CommentMention中。
  3. 删除用户中的记录:级联删除用户中的相关记录 候选资格,UserDocument,评论,事件,提醒, CommentMention 和通知表。

我还想知道循环和多次循环之间是否存在差异,因为循环之间有'或'关键字,这意味着有两个可能的级联路径。

这些表的示意图:diagram

1 个答案:

答案 0 :(得分:1)

说您删除一个用户。这会导致您通过表中的CommentMentions删除他们的 userID

但这还会导致您删除他们编写的评论,这又意味着我们必须通过CommentMentions删除CommentId

两个不同的级联路径导致尝试在CommentMentions中删除。

没有周期。没错SQL Server使用一条消息来涵盖两种不同的情况,但是在某些情况下,消息 do 的两个部分都适用。

如果您尝试为其执行级联删除,则将有一个CreatedByUserId外键循环。


通过查看图表可能最容易看到它。选择一个方向来追逐外键-总是朝着键或总是朝着...另一端 1

如果您可以使用这些FK中的任何一个在两个表之间找到两个不同的路由,则您可能具有多个级联路径,因此您无法在这些路径中的 all 上级联删除。如果您可以找到返回到同一表的路由,则可能存在循环,因此您无法对该路径上FK的 all 级联删除。


1 我从未弄清楚这些行的另一端是什么意思。是要成为链中的链接吗?无限符号?还有吗?