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

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

.ThenInclude has two overloads (when following a collection navigation property). One for TPreviousProperty and other one for ICollection<TPreviousProperty>. 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.
Yes that was the problem, I didn't noticed the overload first because it was missing in intellisense.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.