8
votes

I'm attempting to set up my database using the Entity Framework 7 fluent API to add a self-referencing many-to-many relationship. The class in question looks like:

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

where the intended relationship is that each definition can have an arbitrary amount of children, of any instance. I would expect a separate table with parent/child columns, where each parent can have multiple children, and each child can be on multiple parents.

There are examples of many-to-many, and examples of self-referencing tables, but I can't work out how to combine the two.

2

2 Answers

0
votes

The workaround is to map the join table to an entity. Please look into this.

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

Be sure to configure ChildrenDefinition with a composite key:

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

To navigate, use a Select:

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

Hope this may help you out!

-1
votes

Say for Example, You are having following TWO Classes.

1.  Definition 
2.  Children

For Many to Many RelationShip , You have to put ICollection Parent Class in the Child Class and put the ICollection of Child Class in the Parent Class like below.

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

another Class(Children) should have the ICollection of Definition class.

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

In the DataContext, You Should Create the Mapping for the New Table like below,

 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");
             });
  }

Note: You will be having Separate Table Created With 2 Columns(DefinitionId,ChildrenId). And this Table(ChildrenDefinitions) will enable you to Create the Many to Many Relationship with Definition Class and Children Class.

Hope this may help you out!