-
-
Notifications
You must be signed in to change notification settings - Fork 782
Projections with QueryContext are not projecting collection navigation properties / fields #8179
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
Comments
This is by design as you should have a DataLoader in this place to take over. This way you will get more predictable peformance and also things like nested pagination etc work. There is a new YouTube episode coming next week explaining the dos/donts of projections. |
@michaelstaib Thank you for your answer. I get the point of the more predictable performance and nested pagination, but when using a ORM like Entity Framework, all navigation properties will essentially be useless when using I'm currently in the process of refactoring a fairly big project with an ever bigger domain model, which up till now is using IQueryables (returned via MediatR queries in the Application Layer) in the GraphQL Layer and having DataLoaders declared also in the GraphQL Layer, to instead utilizing QueryContext and handling DataLoaders and Query Logic fully in the Application Layer. Having to create additional Resolvers for every single collection navigation property would propably tripple the workload, as there are a lot of navigation properties where we do not have additional MediatR queries created for and were up till now just relying on EF with navigation properties. Please don't get me wrong, I really appreciate this new feature, but having some opt-in for also handling collections would be a real benefit when using an ORM and migrating from IQueryables to QueryContexts |
What about adding this through source generation? |
Not all navigation properties, only collections. Joining collections leads to cartesian explosion, and how would you paginate the data (for both the root and sub collections)? |
Yes, you are right, I meant collection navigation properties
Up until this change, we made a distinction between collections where we just knew that there won't be many relations - for those we just relied on the navigation properties - and collections where we knew they would have too many results, where we either disabled the field via configuration or created a separate resolver with pagination. We also relied on EF Core's Split Query feature to prevent cartesian explosions. But nonetheless, I think I get the point why this isn't supported anymore. Thanks for your replies, I highly anticipate Michael's YouTube video regarding this topic 😄 |
If you're happy with the old way of doing projections—why change? The new DataLoader-based data APIs are still evolving. We’re actively iterating and adding lots of new features, and I expect that over the next few dot releases, much of our focus will remain on improving GreenDonut. And that brings us to the core point: this is a DataLoader feature. The new data APIs are designed to be more hands-on—they give you control over how things are fetched and by which keys we break things down. If you don’t care much about the SQL being generated or the performance characteristics, then the old projections with split queries might suit you just fine. But the new data APIs are built on top of GreenDonut, not Hot Chocolate. They are fundamentally DataLoader-centric. While we started with EF Core, they’re not limited to ORMs—they’re designed to work with anything you can fetch using DataLoader. Split queries are transparent to the user—you don’t have control over how or when things are split. This feature is really on the other end of the spectrum. Cartesian explosions are just one concern; we’re also looking at how other data features like aggregations fit into layered architectures. Also, in Hot Chocolate, we’ve revamped the paging APIs to give you more control. With the new With these new APIs, you get full control, but that also means you need to be more explicit about what you want. That’s the whole philosophy behind them. It will take us some time to get all the features in that we envision for this space—but it’s very much a feature area where we don’t want “magic.” Looking ahead, we’ll end up with three distinct approaches to working with data APIs—and Fusion will be the overarching layer that can unify them and enable distributed operations:
|
Just as a side note ... we do support collections if they are meant as scalars. We will treat them as scalars. At the moment you can do that by using requirements. Although we are working on a better API for 15.2 |
@michaelstaib Thank you very much for the explanations and the video, this was very informative! We are going to continue the refactoring of our project, I think with the newly provided information we can also resolve our edge cases regarding the collections. I have some additional questions regarding this topic, but I'm not sure if this is the right place for this to ask - if not, I apologize.
Thank you again for your detailed explanations! |
Product
Hot Chocolate
Version
15.1.1
Link to minimal reproduction
https://github.com/invalidoperation/HC_QueryContextCollectionNavigationsReproduction
Steps to reproduce
Run this query in Nitro:
What is expected?
Both
authorsWithQueryContext
andauthorsWithQueryable
should correctly expand and projectbooks
collectionWhat is actually happening?
Only
authorsWithQueryable
correctly expandsbooks
.books
Field is empty forauthorsWithQueryContext
:Expression in
QueryContext.Selector
isroot => new Author() {Name = root.Name}
,books
field is ignored.Relevant log output
Additional context
Collection Fields are not correctly projected when using the new
QueryContext
with HC 15. When usingIQueryable
as return type with projections, this works without issues.I could already trace the root problem to this line: https://github.com/ChilliCream/graphql-platform/blob/main/src/HotChocolate/Core/src/Execution.Projections/SelectionExpressionBuilder.cs#L199
It seems all ListTypes, which are not LeafTypes, are early returned in
SelectionExpressionBuilder.CollectSelection
and not further projected.The text was updated successfully, but these errors were encountered: