C
C#Anton

❔ HotChocolate with IQueryable, apply a required filter on the ef entity

Basically, I'm trying to find a way to configure an IObjectFieldDescriptor by adding a required argument to it, which should in turn apply a filter on the database entity. In this case, I'm adding a companyId argument, and then applying the respective filter manually, before mapping. What should I do to configure this in a simpler way? Let me show you what I have and then what I mean by a better way. This is what I have so far. Don't mind the FieldCollectionQuery and UseBuiltinMiddleware extension methods, they are there to set up the ef core stuff. The argument is the important bit right now.
public sealed class QueryType : ObjectType
{
protected override void Configure(IObjectTypeDescriptor descriptor)
{
descriptor
.FieldCollectionQuery<SupplierGraphDtoType>("suppliers")
.Argument("companyId", a => a.Type<NonNullType<IntType>>())
.UseBuiltinMiddleware<SupplierGraphDtoType>(MiddlewareFlags.All)
.Resolve(ctx =>
{
var q = ctx.DbContext<DataContext>()
.Set<Supplier>()
.AsQueryable();

int companyId = ctx.ArgumentValue<int>("companyId");
q = q.Where(s => s.CompanyId == companyId);

return q.ProjectTo<Supplier, SupplierGraphDto>(ctx);
});
}
}
public sealed class QueryType : ObjectType
{
protected override void Configure(IObjectTypeDescriptor descriptor)
{
descriptor
.FieldCollectionQuery<SupplierGraphDtoType>("suppliers")
.Argument("companyId", a => a.Type<NonNullType<IntType>>())
.UseBuiltinMiddleware<SupplierGraphDtoType>(MiddlewareFlags.All)
.Resolve(ctx =>
{
var q = ctx.DbContext<DataContext>()
.Set<Supplier>()
.AsQueryable();

int companyId = ctx.ArgumentValue<int>("companyId");
q = q.Where(s => s.CompanyId == companyId);

return q.ProjectTo<Supplier, SupplierGraphDto>(ctx);
});
}
}
A
Anton414d ago
And what it should look like in my mind:
descriptor
.FieldCollectionQuery<SupplierGraphDtoType>("suppliers")
.RequiredArgumentFilter(
argumentName: "companyId",
accessorExpression: x => x.CompanyId)
.UseBuiltinMiddleware<SupplierGraphDtoType>(MiddlewareFlags.All)
.Resolve(ctx =>
{
var q = ctx.DbContext<DataContext>()
.Set<Supplier>()
.AsQueryable();

// filters somehow get applied prior to projection

return q.ProjectTo<Supplier, SupplierGraphDto>(ctx);
});
descriptor
.FieldCollectionQuery<SupplierGraphDtoType>("suppliers")
.RequiredArgumentFilter(
argumentName: "companyId",
accessorExpression: x => x.CompanyId)
.UseBuiltinMiddleware<SupplierGraphDtoType>(MiddlewareFlags.All)
.Resolve(ctx =>
{
var q = ctx.DbContext<DataContext>()
.Set<Supplier>()
.AsQueryable();

// filters somehow get applied prior to projection

return q.ProjectTo<Supplier, SupplierGraphDto>(ctx);
});
This looks like I need to split off the ProjectTo call into a middleware that's a bit higher up in the chain, and then apply the filter via another middleware that's just above Resolve. Any ideas? Ah yes, forgot to mention, I also need to validate the whether the user has access to that company, whose id was passed in, which is why using a where filter here won't do.
A
Accord413d ago
Looks like nothing has happened here. I will mark this as stale and this post will be archived until there is new activity.