DotNetCore Entity Framework many-to-many on the same table

c# entity-framework-core many-to-many

Question

I am using DotNetCore 2, and I want to achieve a scenario where I have a single model, that can contain zero or more of the same models.

Consider the following scenario (for simplicity):

  • An engine can consist of many parts (components)
  • Each part can contain zero or more other parts (components)

I want to link these items as such:

System

Id    Name
----------------
1     Drive System

Component

Id    Name
----------------
1     Motor
2     Bearings
3     Couplings
4     Fixtures

With the many-to-many relationship between the System and the Component as such:

SystemComponents

SystemId    ComponentId
-------------------------
1           1

And many to many link on Component (for the lack of better a better name)

ComponentComponents

ParentId    ChildId
---------------------
1           2
1           3
1           4

So in the above scenario can be translated as A Drive System has a component - Motor, and the motor has additional sub-components, 'Bearings', 'Couplings', and 'Fixtures'

The SytemComponent relationship is working. For the ComponentComponent relationship, I have tried the following with my code-first migration:

Component

public class Component 
{
    public Component() 
    {
        SystemComponents = new Collection<SystemComponent>();
        ChildComponents = new Collection<Component>();
    }

    public int Id { get; set; }
    public string Name { get; set; }

    // Needs this for the Many to Many relationship
    public virtual ICollection<SystemComponent> SystemComponents { get; set; }

    // Any component can contain one or more existing components
    public virtual ICollection<Component> ChildComponents { get; set; }
}

ComponentComponent linking model:

public class ComponentComponent
{
    public int ParentComponentID { get; set; }
    public int ChildComponentID { get; set; }

    public Component ParentComponent { get; set; }
    public Component ChildComponent { get; set; }
}

With my ComponentComponent configuration:

public class ComponentComponentConfiguration : IEntityTypeConfiguration<ComponentComponent> {
    public void Configure(EntityTypeBuilder<ComponentComponent> builder) {
        builder.ToTable("ComponentComponent");

        builder.HasKey(cc => new { cc.ParentComponentID, cc.ChildComponentID });

        builder.HasOne(cc => cc.ParentComponent)
            .WithMany(c => c.ComponentComponents)
            .HasForeignKey(cc => cc.ParentComponentID);

        builder.HasOne(cc => cc.ChildComponent)
            .WithMany(c => c.ComponentComponents)
            .HasForeignKey(cc => cc.ChildComponentID);
    }
}

When running the migration I get the following Error:

Cannot create a relationship between 'Component.ComponentComponents' and 'ComponentComponent.ChildComponent', because there already is a relationship between 'Component.ComponentComponents' and 'ComponentComponent.ParentComponent'. Navigation properties can only participate in a single relationship.

How would I achieve such a relationship in Entity Framework in DotNetCore 2?

EDIT

I have uploaded a similar sample project to my github page:

https://github.com/JAspeling/Many-to-Many

1
1
7/31/2018 10:07:39 AM

Accepted Answer

It looks like the issue is in your Component class. Instead of referencing to a collection of components it should look like this

public class Component 
{
    public Component() 
    {
        SystemComponents = new Collection<SystemComponent>();
        ChildComponents = new Collection<ComponentComponent>();
    }

    public int Id { get; set; }
    public string Name { get; set; }

    // Needs this for the Many to Many relationship
    public virtual ICollection<SystemComponent> SystemComponents { get; set; }

    // Any component can contain one or more existing components
    public virtual ICollection<ComponentComponent> ChildComponents { get; set; }
}

You need to make a reference to the mapping table.

https://docs.microsoft.com/de-de/ef/core/modeling/relationships#many-to-many

0
6/28/2018 8:27:50 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow