Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No way to .ThenInclude() multiple sub-properties #4716

Closed
gzak opened this issue Mar 7, 2016 · 15 comments
Closed

No way to .ThenInclude() multiple sub-properties #4716

gzak opened this issue Mar 7, 2016 · 15 comments
Labels
closed-no-further-action The issue is closed and no further action is planned. customer-reported

Comments

@gzak
Copy link

gzak commented Mar 7, 2016

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.

@rowanmiller
Copy link
Contributor

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)

@rowanmiller
Copy link
Contributor

BTW #4490 "More flexible Include API - allow walking back up include tree" is also relevant to this code.

@gzak
Copy link
Author

gzak commented Mar 7, 2016

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.

@Waldspecht
Copy link

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?

@yeganehaym
Copy link

yeganehaym commented Feb 5, 2018

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

@marc9ot
Copy link

marc9ot commented Jul 26, 2018

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)

@eltiare
Copy link

eltiare commented Nov 3, 2018

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.

@nammadhu
Copy link

nammadhu commented Feb 9, 2019

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

@sumiflow
Copy link

sumiflow commented Feb 7, 2020

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.

@ErroneousFatality
Copy link

Any news whether "Include.ThenInclude.AlsoInclude" syntax or similar will be implemented for a more elegant solution to this problem?

@deadmann
Copy link

deadmann commented Sep 2, 2020

It could change to IncludeSibling() or SisterInclude()...

@Uraharadono
Copy link

I can't believe this is still relevant in 6th month of 2021. Just created a query that has 22 lines of code because I had to do Include for every subsequent ThenInclude ...

@rgwebb
Copy link

rgwebb commented Nov 9, 2021

@Uraharadono only 22 lines of code? I just wrote one with 45 lines of Include() and ThenInclude() chaining. Admittedly, each on a new line for readability.

I thought that there surely must be a better way by now but alas!

@ajcvickers ajcvickers added closed-no-further-action The issue is closed and no further action is planned. customer-reported labels Nov 16, 2021
@lsiepel
Copy link

lsiepel commented Feb 16, 2022

Any news whether "Include.ThenInclude.AlsoInclude" syntax or similar will be implemented for a more elegant solution to this problem?

Why is this closed without any follow up?

@ajcvickers
Copy link
Member

@lsiepel This issue was closed in 2016. Changes to the Include syntax are tracked by #4490.

@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-no-further-action The issue is closed and no further action is planned. customer-reported
Projects
None yet
Development

No branches or pull requests