23

I have the following where I am trying to include the addresses of the people in the cities of the countries.

Country country = _db.Countries
               .Include(p=>p.Cities.People.????)
               .Where(....)

Not sure how to work it?

Michal Hosala
  • 5,570
  • 1
  • 22
  • 49
Ian Vink
  • 66,960
  • 104
  • 341
  • 555

2 Answers2

35

You have to add an .Include call for each level in you object hierarchy tree:

 var result = db.Countries
            .Include(m => m.Cities)
            .Include(m => m.Cities.Select(v => v.People))
            .Where(....)

Edit : D.Stanley answer is better in terms of compact code, and works as well, I tend to prefer this syntax in terms of modularity.

rmtz
  • 646
  • 5
  • 5
  • If you are including level 3 childs you dont need to explicitly include level 2 childs `.Include(m => m.Cities)` is not needed here. – Shekhar Pankaj Oct 10 '17 at 06:23
  • Note that inverting the order can in some cases remove the need for the (in my opinion ugly) select statements: `db.People.Include (p => p.City).Include(p => p.City.Country)`. You can end it on a `Select(p => p.City.Country)` to receive a list of countries again. – Flater Jun 11 '18 at 07:30
31

From the documentation:

To include a collection, a collection, and a reference two levels down:

    query.Include(e => e.Level1Collection.Select(l1 => l1.Level2Collection.Select(l2 => l2.Level3Reference))).

So in your case try

Country country = _db.Countries
               .Include(c=>c.Cities.Select(
                   cc => cc.People.Select(
                   p => p.Addresses)))
               .Where(....)

Access to this extension method requires the directive using System.Data.Entity;

Community
  • 1
  • 1
D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • 24
    I'd also mention that the strongly-typed include requires adding: `using System.Data.Entity;`. – Erik Philips Jul 24 '14 at 23:07
  • 7
    For .net core the syntax is now .Include(c=>c.Cities).ThenInclude(cc => cc.People).ThenInclude(p => p.Addresses) see https://docs.efproject.net/en/latest/querying/related-data.html#including-multiple-levels – Jason Aug 05 '16 at 02:51
  • For those still on EF 6.x you can use the non-type checked string version of include `.Include("Cities.People.Addresses")` see: https://learn.microsoft.com/en-us/ef/ef6/querying/related-data#eagerly-loading-multiple-levels – James Close Dec 30 '19 at 12:35