fullstackhero / dotnet-starter-kit

Production Grade Cloud-Ready .NET 8 Starter Kit (Web API + Blazor Client) with Multitenancy Support, and Clean/Modular Architecture that saves roughly 200+ Development Hours! All Batteries Included.
https://fullstackhero.net/dotnet-webapi-boilerplate/
MIT License
5.19k stars 1.56k forks source link

support ThenInclude #247

Closed dsoltesz closed 2 years ago

dsoltesz commented 2 years ago

Is your feature request related to a problem? Please describe. BaseSpecification only supports Include

Describe the solution you'd like Should support Include.ThenInclude

akema-trebla commented 2 years ago

Actually "ThenInclude" is supported if you add the child to the expression using the Includes or IncludeStrings.

My issue though is with the use of magic strings especially when including the children of a collection navigation property.

I'll submit a PR to use typed entities as opposed to magic strings.

dsoltesz commented 2 years ago

Can you provide an example?

akema-trebla commented 2 years ago

var spec = new BaseSpecification<Product>(); spec.Includes.Add(a => a.Brand); var product = await _repository.GetByIdAsync<Product, ProductDetailsDto>(id, spec);

Suppose Brand has a Manufacturer and Manufacturer has an Address, you could include them by chaining them

spec.Includes.Add(a => a.Brand.Manufacturer.Address);

Or you could use the IncludeStrings property on the BaseSpecification

spec.IncludeStrings.Add("Brand.Manufacturer.Address");

But like I said I'm doing some refactoring and I'll submit a PR soon.

dsoltesz commented 2 years ago

Thanks


From: akema-trebla @.> Sent: Friday, December 10, 2021 5:20:42 PM To: fullstackhero/dotnet-webapi-boilerplate @.> Cc: dsoltesz @.>; Author @.> Subject: Re: [fullstackhero/dotnet-webapi-boilerplate] support ThenInclude (Issue #247)

var spec = new BaseSpecification(); spec.Includes.Add(a => a.Brand); var product = await _repository.GetByIdAsync<Product, ProductDetailsDto>(id, spec);

Suppose Brand has a Manufacturer and Manufacturer has an Address, you could include them by chaining them

spec.Includes.Add(a => a.Brand.Manufacturer.Address);

Or you could use the IncludeStrings property on the BaseSpecification

spec.IncludeStrings.Add("Brand.Manufacturer.Address");

But like I said I'm doing some refactoring and I'll submit a PR soon.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/fullstackhero/dotnet-webapi-boilerplate/issues/247#issuecomment-991343053, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AALFFSNCQ46Q62ISBFLNGM3UQJ4LVANCNFSM5JXOIV6A.

dsoltesz commented 2 years ago

that works for single entity but what if brand had a collection of Manufacturers... you need to be able to say Brand.Manufacturers.ThenInclude(man => man.Address)

in EF 6 you can do this spec.Includes.Add(o => o.EpisodeConsumerAdvices.Select(e => e.ConsumerAdvice)); but in EF core you need to use ThenInclude

akema-trebla commented 2 years ago

Yes, I dunno which version of the API you're using but before I submitted #250, you could achieve this using magic strings.

Something like spec.IncludeStrings.Add("Brand.Manufacturers.ConsumerAdvice")

Personally, I'm not a fan of magic strings. So I wanted the repository code to use typed entities as much as possible and especially with Includes.

Now because of the use of repository pattern we can't have a dependency of EFCore in the Application project to make use of IIncludableQueryable to leverage ThenInclude directly. So I tried to bring back the EF 6 approach where you could still include collection navigation properties and their children using Select method.

So from #250 onwards you can include children of collection navigation properties using the Select method like you have above.

dsoltesz commented 2 years ago

Using the select approach wasn't working for me in ef core..that's how I ended up learning about the thenInclude

akema-trebla commented 2 years ago

Using the select approach wasn't working for me in ef core..that's how I ended up learning about the thenInclude

Yes, Select no longer works in EFCore out of the box - You need to use ThenInclude.

But because I wanted to use typed entities and couldn't use the dependency on EFCore, I had to adopt the EF 6 approach in this project.

Hope you get me