【问题标题】:Creating a self-referencing Many to Many relationship in Entity Framework 7在 Entity Framework 7 中创建自引用多对多关系
【发布时间】:2016-10-05 19:55:29
【问题描述】:

我正在尝试使用 Entity Framework 7 fluent API 来设置我的数据库,以添加自引用多对多关系。 有问题的类看起来像:

public class Definition
{
    // Some properties
    public virtual ICollection<Definition> AllowedChildDefinitions { get; set; }
}

其中预期的关系是每个定义可以有任意数量的任何实例的子代。我希望有一个包含父/子列的单独表,其中每个父级可以有多个孩子,每个孩子可以有多个父母。

有多对多的例子和自引用表的例子,但我不知道如何将两者结合起来。

【问题讨论】:

    标签: c# entity-framework asp.net-core entity-framework-core


    【解决方案1】:

    解决方法是将连接表映射到实体。请调查一下。

    public class Definition
    {
       public int Id { get; set; }
       public ICollection<ChildrenDefinition> ChildrenDefinitions{ get; set; }
    }
    
    public class ChildrenDefinition
    {
      public int DefinitionId { get; set; }
      public Definition Definition { get; set; }
    
      public int ChildrenId { get; set; }
      public Children Children { get; set; }
    }
    
    public class Children
    {
        public int Id { get; set; }
        public ICollection<ChildrenDefinition> ChildrenDefinitions{ get; set; }
    }
    

    请务必使用复合键配置 ChildrenDefinition:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
       modelBuilder.Entity<ChildrenDefinition>().HasKey(x => new {  x.DefinitionId, x.ChildrenId });
    }
    

    要导航,请使用 Select:

    // Children.Definition
    var definitions = Children.ChildrenDefinitions.Select(c => c.Definition);
    

    希望对您有所帮助!

    【讨论】:

    • 虽然您的答案涵盖了基本的多对多关系,但 OP 要求自引用多对多。可悲的是,这个答案并没有解决这个问题
    【解决方案2】:

    例如,您有以下两个课程。

    1.  Definition 
    2.  Children
    

    对于多对多关系,您必须将 ICollection 父类放在子类中,并将子类的 ICollection 放在父类中,如下所示。

    public class Definition
     {
      // Some properties
      public virtual ICollection<Children> Childrens { get; set; }
     }
    

    另一个 Class(Children) 应该有 ICollection of Definition 类。

      public class Children
      {
       // Some properties
       public virtual ICollection<Definition> Definitions { get; set; }
      }
    

    在 DataContext 中,您应该为新表创建映射,如下所示,

     protected override void OnModelCreating(ModelBuilder modelBuilder)
     {
    
       modelBuilder.Entity<Definition>()
                 .HasMany(l => l.Childrens)
                 .WithMany(o => o.Definitions)
                 .Map(m =>
                 {
                     m.MapLeftKey("DefinitionId");
                     m.MapRightKey("ChildrenId");
                     m.ToTable("ChildrenDefinitions");
                 });
      }
    

    注意:您将使用 2 列(DefinitionId、ChildrenId)创建单独的表。而这个表(ChildrenDefinitions)将使您能够创建与定义类和子类的多对多关系。

    希望对您有所帮助!

    【讨论】:

    • 不幸的是 HasMany().WithMany() 在 EF7 中看起来是不可能的,因为可以对 HasMany() 的结果使用的唯一方法是 WithOne()。
    猜你喜欢
    • 2020-07-22
    • 2017-02-27
    • 2016-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多