ChilliCream / graphql-platform

Welcome to the home of the Hot Chocolate GraphQL server for .NET, the Strawberry Shake GraphQL client for .NET and Banana Cake Pop the awesome Monaco based GraphQL IDE.
https://chillicream.com
MIT License
4.96k stars 722 forks source link

Add an optional property parameter to DataLoaders methods. #7081

Open orlandommb opened 2 weeks ago

orlandommb commented 2 weeks ago

Product

Green Donut

Is your feature request related to a problem?

I don't think its a problem is more of a inconvenience, if an Entity has relationships with more than one Entity, and i want to able to include those entities in my query i have to build one DataLoader for each relationship (im using EF Core) because there's no way to pass the property that i need to query for in the where clause of ef core.

For example, the models Products, Category and Company. Products has a CategoryId and CompanyId foreign keys, and Company and Category models have List Products navigation properties,

If i query for Company and want to include Products in my query i got a build a GroupedDataLoader that searches for products like:

context.Products.Where(p=> keys.Contains( p.CompanyId ))

If i query for Category and want to include Products in my query i got a build a GroupedDataLoader that searches for products like:

context.Products.Where(p=> keys.Contains( p.CategoryId ))

Right now my Products model has relationships with:

  1. Company
  2. Branch
  3. Category
  4. SubCategory
  5. Unit
  6. Tax

this means i have to make one GroupedDataLoader for each, at least thats how i know how to do it right now, don't know if theres a better way to do it.

The solution you'd like

Passing the property as a parameter in some way is the best solution that comes to my mind. I know that HotChocolate its made to work with multiple database providers but maybe with an optional parameter in the LoadBatchAsync method might work, something like Product.CategoryId.

michaelstaib commented 1 week ago

@PascalSenn would the observable cache solve this?

PascalSenn commented 1 week ago

@michaelstaib
Observable cache would not reduce the number of data loaders, but the total number of fetches.

You still need to have a DataLoader from each direction, but once fetched, the order data loaders could subscribe to the cache and also get prefilled.

Meaning, if I load the 2 via the ProductByCompanyIdDataLoader and I get { id: 1, companyId: 2, categoryId: 3}, then a call to ProductByCategoryIdDataLoader with id 3 would already be in the cache.

On another note, the behaviour that @orlandommb describes could theoretically already done with a datalaoder that has a polymorphic key.

public record ProductKey() 
{
     public record CustomerId(Guid CustomerId) : ProductKey
     public record BranchId(Guid CustomerId) : ProductKey
     public record CategoryId(Guid CustomerId) : ProductKey
     ...
}
PascalSenn commented 1 week ago

Thinking about it more, the observable cache would not help at all with GroupedDataLoaders, as there is no way to know if you have fetched all Products of a Category already.