在 GraphQL HotChocolate 上过滤 EF 核心导航 属性
Filter EF Core Navigation property on GraphQL HotChocolate
我正在将 HotChocolate (11.2.2) 与 EF Core 一起使用,并希望过滤子 属性。根据 GraphQL 文档,这应该可以通过在导航 属性 上使用 filter 关键字来实现,但是 HotChocolate 只是失败了。
我的架构:
type A {
Name: string,
RefTo: [B]
}
type B {
TypeName: string,
Value: int
}
这是由 EF 支持的,我向 HotChocolate 提供了一个 IQueryable<A>
。
[UsePaging]
[UseProjection]
[UseFiltering]
[UseSorting]
public IQueryable<A> GetAs([Service] Context db) => db.As.AsSingleQuery().AsNoTrackingWithIdentityResolution();
现在我只想包含 TypeName
等于 "ExampleType"
的那些 B
,如下所示:
query {
As {
Name,
RefTo(where: { TypeName: { eq: "ExampleType" } })
{
TypeName,
Value
}
}
}
但是 HotChcolate 似乎不理解这一点并说:
Unknown argument "where" on field "A.RefTo".validation
是否可以使用 EF Core 模型过滤导航属性?
您也必须向 RefTo 添加过滤
[UseFiltering]
public ICollection<A> RefTo {get; set;}
如果您想将 UseFiltering
、UseSorting
等应用于结果类型为 ICollection
的所有字段,您可以使用 TypeInterceptor
:
using System;
using System.Collections.Generic;
using HotChocolate.Configuration;
using HotChocolate.Types;
using HotChocolate.Types.Descriptors;
using HotChocolate.Types.Descriptors.Definitions;
namespace MyApp
{
public class FilterCollectionTypeInterceptor : TypeInterceptor
{
private static bool IsCollectionType(Type t)
=> t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ICollection<>);
public override void OnBeforeRegisterDependencies(ITypeDiscoveryContext discoveryContext, DefinitionBase? definition,
IDictionary<string, object?> contextData)
{
if (definition is not ObjectTypeDefinition objectTypeDefinition) return;
for (var i = 0; i < objectTypeDefinition.Fields.Count; i++)
{
var field = objectTypeDefinition.Fields[i];
if (field.ResultType is null || !IsCollectionType(field.ResultType)) continue;
var descriptor = field.ToDescriptor(discoveryContext.DescriptorContext)
.UseFiltering()
.UseSorting();
objectTypeDefinition.Fields[i] = descriptor.ToDefinition();
}
}
}
}
我正在将 HotChocolate (11.2.2) 与 EF Core 一起使用,并希望过滤子 属性。根据 GraphQL 文档,这应该可以通过在导航 属性 上使用 filter 关键字来实现,但是 HotChocolate 只是失败了。
我的架构:
type A {
Name: string,
RefTo: [B]
}
type B {
TypeName: string,
Value: int
}
这是由 EF 支持的,我向 HotChocolate 提供了一个 IQueryable<A>
。
[UsePaging]
[UseProjection]
[UseFiltering]
[UseSorting]
public IQueryable<A> GetAs([Service] Context db) => db.As.AsSingleQuery().AsNoTrackingWithIdentityResolution();
现在我只想包含 TypeName
等于 "ExampleType"
的那些 B
,如下所示:
query {
As {
Name,
RefTo(where: { TypeName: { eq: "ExampleType" } })
{
TypeName,
Value
}
}
}
但是 HotChcolate 似乎不理解这一点并说:
Unknown argument "where" on field "A.RefTo".validation
是否可以使用 EF Core 模型过滤导航属性?
您也必须向 RefTo 添加过滤
[UseFiltering]
public ICollection<A> RefTo {get; set;}
如果您想将 UseFiltering
、UseSorting
等应用于结果类型为 ICollection
的所有字段,您可以使用 TypeInterceptor
:
using System;
using System.Collections.Generic;
using HotChocolate.Configuration;
using HotChocolate.Types;
using HotChocolate.Types.Descriptors;
using HotChocolate.Types.Descriptors.Definitions;
namespace MyApp
{
public class FilterCollectionTypeInterceptor : TypeInterceptor
{
private static bool IsCollectionType(Type t)
=> t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ICollection<>);
public override void OnBeforeRegisterDependencies(ITypeDiscoveryContext discoveryContext, DefinitionBase? definition,
IDictionary<string, object?> contextData)
{
if (definition is not ObjectTypeDefinition objectTypeDefinition) return;
for (var i = 0; i < objectTypeDefinition.Fields.Count; i++)
{
var field = objectTypeDefinition.Fields[i];
if (field.ResultType is null || !IsCollectionType(field.ResultType)) continue;
var descriptor = field.ToDescriptor(discoveryContext.DescriptorContext)
.UseFiltering()
.UseSorting();
objectTypeDefinition.Fields[i] = descriptor.ToDefinition();
}
}
}
}