Search code examples
c#entity-frameworklinq-to-entitieseager-loading

Entity Framework eager loading entity list within entity list


I've encountered a problem: I have a table that has a reference to another table, that has a list of references to another table, which has another list of references, and I want to eager load all of this.

Basically, the idea is:

public class User {
     public ClassL1 l1 { get; set; }
}

ClassL1 {
    public List<ClassL2> l2 { get; set; }
}

ClassL2 {
    public List<ClassL3> l3 { get; set; }
}

ClassL3 {
    //some basic string or int values
}

And currently, I'm trying to load it with something like this, but to no avail:

user = context.Users
  .Where(u => u.UserName == model.Username)
  .Include(u => u.l1)
  .ThenInclude(l1 => l1.l2)
  .ThenInclude(l2List => l2List.Select(l2Single => l2Single.l3))//This doesn't work
  //.Include(u => u.l1.l2.Select(l2Single => l2Single.l3)) //Neither does this
  .First();

How am I supposed to load a list of lists, if select isn't working? Any help would be appreciated.

EDIT: Well, since there apparently is an open bug on this, I went with a stupid fix, and made it work like this:

user = context.Users
  .Where(u => u.UserName == model.Username)
  .Include(u => u.l1)
  .ThenInclude(l1 => l1.l2)
  .First();
for (int i = 0; i < user.l1.l2.Count; i++) 
{
  user.l1.l2[i].l3 = context.l3DB
    .Where(p => p.l2.Id == user.l1.l2[i].Id)
    .ToList();
}

And for this to work, I added references up(to parents) inside the classes. for example:

public class ClassL2 {
    public List<ClassL3> l3 { get; set; }
    public ClassL1 l1 { get; set; }//reference to parent
}

Solution

  • How about this:

    user = (from usr in context.Users
            where usr.UserName == model.Username
            select new
            {
                usr,
                usr.l1,
                l2List = from l2 in usr.l1.l2
                        select new
                        {
                            l2,
                            l2.l3
                        }
            }).AsEnumerable().Select(m => m.usr).First();