0

I have a many-to-many relation between parents and childs using a relation table cause those relations are not automatically supported in EF Core yet:

class Parent{
    [Key]
    public int Id{get;set;}
    public List<ParentChild> ParentChilds{get;set;}
}

class Child{
    [Key]
    public int Id{get;set;}
    public List<ParentChild> ParentChilds{get;set;}
}

class ParentChild{
    public int ParentId{get;set;}
    public Parent Parent{get;set;}
    public int ChildId{get;set;}
    public Child Child{get;set;}
}

For editing the parent, I need to get ALL of his childs. Seems like a job for Include()

var db = new MyDbContext();
var parentWithChilds = db.Parents.Include(p => p.ParentChilds)
    .FirstOrDefault(p => p.Id == 1);

This gave me the list of ParentChild istances. But the Child entity of ParentChild isn't loaded automatically, so I only have the Id of the child, but not the Child object itself which is needed for me. I found ThenInclude which seems to be designed for such cases and from examples like this I did the following:

var parentWithChilds = db.Parents.Include(p => p.ParentChilds)
    .ThenInclude(p => p.Select(x => x.Child))
    .FirstOrDefault(p => p.Id == 1);

But it throws an exception:

The property expression 'p => {from ParentChild x in p select [x].Child => FirstOrDefault()}' is not valid. The expression should represent a property access: 't => t.MyProperty'.

So how can this be done? I would like to avoid unnecessary queries like fetching the entity manually this way:

user.ParentChilds.ForEach(pc => pc.Child = db.Childs.FirstOrDefault(x => x.Id == pc.ChildId));
Community
  • 1
  • 1
Lion
  • 16,606
  • 23
  • 86
  • 148

1 Answers1

3

Seems like I misunderstand the usage of ThenInclude since it refers to the sub-entity. Having a list its possible to define the entity to load also on lists like this:

var parentWithChilds = db.Parents.Include(p => p.ParentChilds)
    .ThenInclude(p => p.Child)
    .FirstOrDefault(p => p.Id == 1);

Visual Studio has issues showing those overload in intellisense, but its there and wouldn't result in errors.

Lion
  • 16,606
  • 23
  • 86
  • 148
  • 4
    `.ThenInclude` has two overloads (when following a collection navigation property). One for `TPreviousProperty` and other one for `ICollection`. For some people Visual Studio seems always to show intellisense for the `TPreviousProperty` variant and only showing the collection extension methods rather than the model. But when typing the property name without autocomplete, it will then select the correct one (like you did with `.ThenInclude(p => p.Child)` and not show an compiler error. – Tseng Oct 30 '16 at 14:09
  • Yes that was the problem, I didn't noticed the overload first because it was missing in intellisense. – Lion Oct 30 '16 at 14:17