Suppose I have the following entities:
public class A
{
public int Id { get; set; }
public int BId { get; set; }
public virtual B B { get; set; }
}
public class B
{
public int Id { get; set; }
public int C1Id { get; set; }
public int C2Id { get; set; }
public virtual C C1 { get; set; }
public virtual C C2 { get; set; }
}
public class C
{
public int Id { get; set; }
}
Now suppose I want to retrieve all A
's and include their B
's and both of B
's C
sub-properties.
I can do db.A.Include(a => a.B).ThenInclude(b => b.C1)
to include one of B
's C
sub-properties, but as far as I can tell, there's no way to include both of B
's C
sub-properties. If I tack on another .Include()
, I'm dealing with A
's. If I tack on anther .ThenInclude()
, I'm now dealing with C
's. There's no way to deal with B
's beyond the first call to .ThenInclude()
.
I propose that the IIncludableQueryable
interface should also expose an .AndInclude()
method, which can be tacked onto a call to .ThenInclude()
to continue accessing the associated property.
Here is what you are after...
db.A
.Include(a => a.B).ThenInclude(b => b.C1)
.Include(a => a.B).ThenInclude(b => b.C2)
BTW because these are reference (and not collection) properties, you can do this for short. ThenInclude only becomes mandatory when you want to include after a collection navigation property.
db.A
.Include(a => a.B.C1)
.Include(a => a.B.C2)
BTW https://github.com/aspnet/EntityFramework/issues/4490 "More flexible Include API - allow walking back up include tree" is also relevant to this code.
Thanks @rowanmiller, makes sense to me. I was about to try the former approach, but the latter one is more compact so I'll switch to that. Feel free to close this issue if appropriate.
Is there any restriction on how deep you can go with ThenInclude
?
Because up to level three (Info
)everything works fine. When I include level four (Details
) it is not returned or included as an object.
Company company = _context.Companies
.Include(c => c.Users)
.Include(c => c.Projects)
.ThenInclude(p => p.Specifications)
.ThenInclude(spec => spec.Info)
.ThenInclude(info => info.Details)
.Include(c => c.Projects)
.ThenInclude(p => p.Specifications)
.ThenInclude(spec => spec.Files)
.Where(t => t.CompanyId.Equals(companyId))
.FirstOrDefault();
The details
objects are missing in the query and not returned. Any idea?
it would be great this substitute syntax instead of repeat one thing consecutively
return _cart
.Include(x => x.GameItems)
.ThenInclude(x=>x.Game)
.ThenInclude(x=>new{x.League,x.Host,x.Guest})
.AsQueryable();
instead of
`
return _cart
.Include(x => x.GameItems)
.ThenInclude(x=>x.Game)
.ThenInclude(x=>x.League)
.Include(x => x.GameItems)
.ThenInclude(x=>x.Game)
.ThenInclude(x=>x.Host)
.Include(x => x.GameItems)
.ThenInclude(x=>x.Game)
.ThenInclude(x=>x.Guest)
.AsQueryable();
`
it's more comprehensible and shorter and easier
After doing this how exactly would I get a where condition from either C1 or C2? seems not to work when I try it with my repository pattern and EF6. Any leads here?
db.A
.Include(a => a.B.C1)
.Include(a => a.B.C2)
I also get errors when I try to use this code in EF Core:
db.A
.Include(a => a.B.C1)
.Include(a => a.B.C2)
I keep seeing this method mentioned, yet have never gotten it to work.
include theinclude both works fine... b ut only problem is intellisense not identifying or showing the methods just type and then proceed all works fine ...
var res = await _context.Diseases.Include(x => x.Disease2Symptom)
.ThenInclude(z => z.Symptom).ToListAsync();
include theinclude both works fine... b ut only problem is intellisense not identifying or showing the methods just type and then proceed all works fine ...
var res = await _context.Diseases.Include(x => x.Disease2Symptom) .ThenInclude(z => z.Symptom).ToListAsync();
Thanks. It took me a long time to realize that what I was trying to do was perfectly valid but that it just wasn't showing in intellisense. I should have just typed it anyway.
Example:
intellisense works fine here:
from q in db.SecurityGroupPermissions
.Include(x => x.SecurityAction)
intellisense does not work on the last item here. A list will pop up but it won't have SecurityAction in the popup:
from q in db.SecurityGroups
.Include(x => x.SecurityGroupPermissions)
.ThenInclude(x => x.SecurityAction)
Once I ignored intellisense and typed it out anyway then it built and ran correctly.
Any news whether "Include.ThenInclude.AlsoInclude" syntax or similar will be implemented for a more elegant solution to this problem?
It could change to IncludeSibling() or SisterInclude()...
Most helpful comment
Here is what you are after...
BTW because these are reference (and not collection) properties, you can do this for short. ThenInclude only becomes mandatory when you want to include after a collection navigation property.