多对多的自我引用关系

我是EF的新手。 我遇到了创建多对多自引用关系的问题。 我尝试使用以下解决方案: entity framework核心:与同一实体的多对多关系

我的实体:

public class WordEntity { public long Id { get; set; } public string Name { get; set; } public string Json { get; set; } public virtual List Sinonyms { get; set; } } public class WordSinonymEntity { public long WordId { get; set; } public virtual WordEntity Word { get; set; } public long SinonymId { get; set; } public virtual WordEntity Sinonym { get; set; } } 

和下一个配置:

  modelBuilder.Entity() .HasOne(pt => pt.Sinonym) .WithMany(p => p.Sinonyms) .HasForeignKey(pt => pt.SinonymId); modelBuilder.Entity() .HasOne(pt => pt.Word) .WithMany(t => t.Sinonyms) .HasForeignKey(pt => pt.WordId);` 

但它导致下一个例外。

System.InvalidOperationException:’无法在’WordEntity.Sinonyms’和’WordSinonymEntity.Word’之间创建关系,因为’WordEntity.Sinonyms’和’WordSinonymEntity.Sinonym’之间已经存在关系。 导航属性只能参与一个关系。

有没有人可以帮助我,或者可能会建议一些例子来学习? 谢谢。

你关注的post肯定是错的。

每个集合或引用导航属性只能单个关系的一部分。 虽然与显式连接实体的多对多关系是通过两个一对多关系实现的。 连接实体包含两个引用导航属性,但主实体只有一个集合导航属性,该属性必须与其中一个相关联,但不能与两者相关联。

解决此问题的一种方法是添加第二个集合导航属性:

 public class WordEntity { public long Id { get; set; } public string Name { get; set; } public string Json { get; set; } public virtual List Sinonyms { get; set; } public virtual List SinonymOf { get; set; } // <-- } 

并通过流畅的API指定关联:

 modelBuilder.Entity() .HasOne(pt => pt.Sinonym) .WithMany(p => p.SinonymOf) // <-- .HasForeignKey(pt => pt.SinonymId) .OnDelete(DeleteBehavior.Restrict); // see the note at the end modelBuilder.Entity() .HasOne(pt => pt.Word) .WithMany(t => t.Sinonyms) .HasForeignKey(pt => pt.WordId); 

另一种方法是保持模型WordSinonymEntity.Sinonym ,但将WordSinonymEntity.Sinonym映射到单向关联(使用refeference navigation属性,没有相应的集合导航属性):

 modelBuilder.Entity() .HasOne(pt => pt.Sinonym) .WithMany() // <-- .HasForeignKey(pt => pt.SinonymId) .OnDelete(DeleteBehavior.Restrict); // see the note at the end modelBuilder.Entity() .HasOne(pt => pt.Word) .WithMany(t => t.Sinonyms) .HasForeignKey(pt => pt.WordId); 

只需确保WithMany完全匹配相应导航属性的存在/不存在。

请注意,在这两种情况下,您必须关闭至少一个关系的删除级联,并在删除主实体之前手动删除相关的连接实体,因为自引用关系总是引入可能的周期或多个级联路径问题,从而阻止使用级联删除。