多对多自我参照关系

我是EF的新手。而且我遇到了创建多对多自引用关系的问题。我尝试使用以下解决方案:

实体框架核心:与同一实体的多对多关系

我的实体:

public class WordEntity

{

public long Id { get; set; }

public string Name { get; set; }

public string Json { get; set; }

public virtual List<WordSinonymEntity> 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<WordSinonymEntity>()

.HasOne(pt => pt.Sinonym)

.WithMany(p => p.Sinonyms)

.HasForeignKey(pt => pt.SinonymId);

modelBuilder.Entity<WordSinonymEntity>()

.HasOne(pt => pt.Word)

.WithMany(t => t.Sinonyms)

.HasForeignKey(pt => pt.WordId);`

但这会导致下一个异常。

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

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

回答:

您关注的帖子肯定是错误的。

每个集合或参考导航属性 只能单个 关系的一部分。与显式联接实体的多对多关系是通过 两个 一对多关系实现的。联接实体包含 两个

参考导航属性,但主要实体仅具有 单个 集合导航属性,该属性必须与其中一个相关联,但不能与两者相关联。

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

public class WordEntity

{

public long Id { get; set; }

public string Name { get; set; }

public string Json { get; set; }

public virtual List<WordSinonymEntity> Sinonyms { get; set; }

public virtual List<WordSinonymEntity> SinonymOf { get; set; } // <--

}

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

modelBuilder.Entity<WordSinonymEntity>()

.HasOne(pt => pt.Sinonym)

.WithMany(p => p.SinonymOf) // <--

.HasForeignKey(pt => pt.SinonymId)

.OnDelete(DeleteBehavior.Restrict); // see the note at the end

modelBuilder.Entity<WordSinonymEntity>()

.HasOne(pt => pt.Word)

.WithMany(t => t.Sinonyms)

.HasForeignKey(pt => pt.WordId);

另一种方法是保持模型不变,但将模型映射WordSinonymEntity.Sinonym单向

关联(具有参考导航属性,而没有对应的集合导航属性):

modelBuilder.Entity<WordSinonymEntity>()

.HasOne(pt => pt.Sinonym)

.WithMany() // <--

.HasForeignKey(pt => pt.SinonymId)

.OnDelete(DeleteBehavior.Restrict); // see the note at the end

modelBuilder.Entity<WordSinonymEntity>()

.HasOne(pt => pt.Word)

.WithMany(t => t.Sinonyms)

.HasForeignKey(pt => pt.WordId);

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

请注意,在两种情况下,您都必须关闭至少一种关系的删除级联,并在删除主实体之前手动删除相关的联接实体,因为自引用关系始终会引入 可能的循环或多个级联路径

问题,从而阻止使用级联删除。

以上是 多对多自我参照关系 的全部内容, 来源链接: utcz.com/qa/400127.html

回到顶部