Search code examples
c#entity-frameworklinqentity-framework-6linq-to-entities

How do I load a child collection of entities when a link table (and class) exists?


My many-to-many relationship requires payload data in the link table (the weight field).

public class Formula
{
    public int ID { get; set; }
    ...
    public virtual ICollection<FormulaComponent> FormulaComponents { get; set; }
}

public class Component
{
    public int ID { get; set; }
    ...
    public virtual ICollection<FormulaComponent> FormulaComponents { get; set; }
}

public class FormulaComponent
{
    [Key, Column(Order = 0)]
    public int FormulaID { get; set; }

    [Key, Column(Order = 1)]
    public int ComponentID { get; set; }

    [ForeignKey("FormulaID")]
    public virtual Formula Formula { get; set; }

    [ForeignKey("ComponentID")]
    public virtual Component Component { get; set; }

    public double? Weight { get; set; }
}

I'm struggling with how to use linq to load child data for a parent entity (components for a specific formula). My code was working before payload data was required. When I had no class representing the link table and the child was a property of the parent (ICollection<Component>) here is how I loaded child data in a disconnected scenario:

_context.Entry(Formula).Collection(f => f.Components).Load();

Since the child collection is no longer a property of the parent I tried this:

_context.Entry(Formula).Collection(f => f.FormulaComponents).Load();

But that only gets the link table data. Since the Components are a property of the link table I suspect I need to add a Select or SelectMany but I can't get the syntax right:

_context.Entry(Formula).Collection(f => f.FormulaComponents.Select(???)).Load();

Any help will be much appreciated.


Solution

  • I'm answering my own question here. I didn't realize that the child Components entities were eager loaded along with FormulaComponents. So this line of code (in the question) actually worked:

    _context.Entry(Formula).Collection(f => f.FormulaComponents).Load();
    

    So when I said "But that only gets the link table data" I was actually wrong. It loads exactly what I wanted loaded.