Reputation: 73
So I'm trying to figure out how to tell EfCore when to apply an include to an IQueryable object based on whether the GraphQl request from the client actually includes the related object.
Example:
2 Classes: Person, Payment
Theses are kept in 2 different tables and related Person -> Payment in a one to many relationship
I have 1 GraphQl Query set up to retrieve all people in the Database:
[UseFiltering]
[UseDbContext(typeof(DbAccess))]
public IQueryable<Person> GetPeople([ScopedService] DbAccess db)
{
return db.People;
}
This returns just the fields in the People table ex: query: {people{sso,payments{amount, recipient{compayName}}}} response: { "data": { "people": [ { "sso": "000-00-0003", "payments": null } ] } }
In order to get the payments my GetPeople func needs to be changed to
[UseFiltering]
[UseDbContext(typeof(DbAccess))]
public IQueryable<Person> GetPeople([ScopedService] DbAccess db)
{
return db.People.Include(p => p.Payments);
}
This works but places an unneeded strain when the payments aren't part of the request (as the Include will run every time).
What I would like to do would be something like:
var baseQuery = db.People;
if (graphqlRequestIncludePayments)
{
baseQuery.Include(p => p.Payments);
}
return baseQuery;
But I cannot figure out how to check the GraphQl query to see if payments is requested. I know GraphQl will remove the excess data before returning to the consumer but that can be a lot of wasted bandwidth and memory on the server side.
I feel like there is a way to do this in the Hotchocolate ObjectType.Configure function but I cant see how.
Any help would be much appreciated, thanks :)
Upvotes: 0
Views: 1655
Reputation: 1
I was facing the same issue. there is a very small catch when using projections that I figured out after reading this page multiple times https://chillicream.com/docs/hotchocolate/v13/fetching-data/projections...
The catch is the note that we generally tend to skip. the note goes as "Note: Projections currently need a public setter on fields they operate on in order to function correctly. Otherwise the default constructed value will be returned upon query."
I checked my model and could see that my model was only having a public getter and not a setter and so I was getting the default value that was empty list. After adding a public setter, it worked perfectly.
Hope this helps.
Upvotes: 0