62

How do I include a child of a child entitiy?

Ie, Jobs have Quotes which have QuoteItems

var job = db.Jobs
            .Where(x => x.JobID == id)
            .Include(x => x.Quotes)
            .Include(x => x.Quotes.QuoteItems) // This doesn't work
            .SingleOrDefault();

Just to be clearer - I'm trying to retrieve a single Job item, and it's associated Quotes (one to many) and for each Quote the associated QuoteItems (One Quote can have many QuoteItems)

The reason I'm asking is because in my Quote Index view I'm trying to show the Total of all the Quote items for each Quote by SUMming the Subtotal, but it's coming out as 0. I'm calling the Subtotal like this:

@item.QuoteItem.Sum(p => p.Subtotal)

I believe the reason I have this issue is that my Linq query above isn't retrieving the associated QuoteItems for each Quote.

4
  • you probably got compiler or syntax error right ? Commented Jun 9, 2014 at 12:19
  • Yeah, I'm pretty sure that's not the syntax, just wanted to demonstrate what I was after Commented Jun 9, 2014 at 12:20
  • Did you miss an entityframework tag btw? Commented Jun 9, 2014 at 12:21
  • Possible duplicate of How to include a child object's child object in Entity Framework 5 Commented Sep 4, 2018 at 12:55

4 Answers 4

66

To get a job and eager load all its quotes and their quoteitems, you write:

var job = db.Jobs
        .Include(x => x.Quotes.Select(q => q.QuoteItems))
        .Where(x => x.JobID == id)
        .SingleOrDefault();

You might need SelectMany instead of Select if QuoteItems is a collection too.

Note to others; The strongly typed Include() method is an extension method so you need to include using System.Data.Entity; at the top of your file.

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

Comments

56

The method in the accepted answer doesn't work in .NET Core.

For anyone using .NET Core, while the magic string way does work, the cleaner way to do it would be ThenInclude:

var job = db.Jobs
        .Where(x => x.JobID == id)
        .Include(x => x.Quotes)
        .ThenInclude(x => x.QuoteItems)
        .SingleOrDefault();

Source: Work with data in ASP.NET Core Apps | Microsoft Learn

3 Comments

This was the right answer for me. I have children of children and it seems that you can nest pretty deep with this, where the "magic string" doesn't work.
I agree, this works nicely and is somewhat clean.
how do you include another ThenInclude if Quotes have another collection besides QuoteItems
31

This will do the job (given that we are talking entity framework and you want to fetch child-entities):

var job = db.Jobs
            .Include(x => x.Quotes) // include the "Job.Quotes" relation and data
            .Include("Quotes.QuoteItems") // include the "Job.Quotes.QuoteItems" relation with data
            .Where(x => x.JobID == id) // going on the original Job.JobID
            .SingleOrDefault(); // fetches the first hit from db.

For more information about the Include statement have a look at this: https://learn.microsoft.com/en-us/dotnet/api/system.data.objects.objectquery-1.include

This answer has been getting upvotes throught the years, so I'd just like to clarify, try https://stackoverflow.com/a/24120209/691294 first. This answer is for those cases where all else fails and you have to resort to a black magic solution (i.e. using magic strings).

8 Comments

have you tried to use .Include after where clause ?
This is a fairly bizarre answer.
@DanielKelley Eh? ObjectQuery? It's the way you do it sadly.
@RamyMohamed Ty for pointing it out, Include is only valid on object queries.
I Think this is good, but iirc, you don't need to have the first .include line, because it will be included as part of the second include line, so you just need the reflective call, and not the first quotes call.
|
9

This did the trick for me as @flindeberg said here . Just added checking if there are children in each parent item in the list

 List<WCF.DAL.Company> companies = dbCtx.Companies.Where(x=>x.CompanyBranches.Count > 0)
                            .Include(c => c.CompanyBranches)
                            .Include("CompanyBranches.Address")
                            .ToList();

1 Comment

It can be better if you don't use magic strings: .Include(${nameof(Companies.CompanyBranches)}.{nameof(CompanyBranch.Address)})

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.