多对多自引用关系 [英] Many-to-many self referencing relationship

查看:23
本文介绍了多对多自引用关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 EF 的新手.我在创建多对多自引用关系时遇到了问题.我尝试使用以下解决方案:Entity Framework Core:与同一实体的多对多关系

I am new in EF. And I ran into a problem with creation many-to-many self referencing relation. I've tried to use solution from: Entity Framework Core: many-to-many relationship with same entity

我的实体:

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);`

但这会导致下一个异常.

but it leads to next exception.

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

System.InvalidOperationException: 'Cannot create a relationship between 'WordEntity.Sinonyms' and 'WordSinonymEntity.Word', because there already is a relationship between 'WordEntity.Sinonyms' and 'WordSinonymEntity.Sinonym'. Navigation properties can only participate in a single relationship.'

有没有人可以帮助我或者可以推荐一些例子来学习?谢谢.

Does anyone can help me or may be suggest some examples to learn ? Thanks.

推荐答案

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

The post you are following is definitely wrong.

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

Every collection or reference navigation property can only be a part of a single relationship. While many to many relationship with explicit join entity is implemented with two one to many relationships. The join entity contains two reference navigation properties, but the main entity has only single collection navigation property, which has to be associated with one of them, but not with both.

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

One way to resolve the issue is to add a second collection navigation property:

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; } // <--
}

并通过 fluent API 指定关联:

and specify the associations via fluent 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 映射到 单向 关联(具有参考导航属性,没有相应的集合导航属性):

Another way is to leave the model as is, but map the WordSinonymEntity.Sinonym to unidirectional association (with refeference navigation property and no corresponding collection navigation property):

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 与相应导航属性的存在/不存在完全匹配.

Just make sure that WithMany exactly matches the presence/absence of the corresponding navigation property.

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

Note that in both cases you have to turn the delete cascade off for at least one of the relationships and manually delete the related join entities before deleting the main entity, because self referencing relationships always introduce possible cycles or multiple cascade path issue, preventing the usage of cascade delete.

这篇关于多对多自引用关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆