如何在 ASP.NET Core GraphQL 中访问嵌套字段中的参数
How to access arguments in nested fields in ASP.NET Core GraphQL
我有一个字段 "statistics" 的查询,它是一个具有三个不同累加值的子查询。我希望能够为统计数据提供国家/地区参数,然后在子查询中不同字段的解析器中访问该参数。
我正在使用 GraphQL.Server.Transports.AspNetCore nuget 包。子查询使用 IDependencyResolver 解析,因为它对不同字段的解析器中使用的服务有一些依赖性。
我尝试通过 ResolveFieldContext 访问父级,但它似乎不可用。在名为 "Source" 的上下文中有一个 属性,但它指的是子查询对象。
如果我们查看 GraphQL 的其他实现,似乎应该是可能的,但我不知道如何从 ASP.NET Core
获得结果
下面的代码显示了名为 "CompanyGroupQuery"
的主查询的一部分
Field<CompanyStatisticsQuery>(
"statistics",
arguments: new QueryArguments(new QueryArgument<StringGraphType> { Name = "country" }),
resolve: context => resolver.Resolve<CompanyStatisticsQuery>()
);
子查询看起来像这样
Field<IntGraphType>(
"completeInvoicesCount",
resolve: context => {
// This is to show what I'm trying to achieve
var parent = context.Parent;
var companyId = context.GetArgument<string>("companyId");
var country = context.GetArgument<string>("country");
return null;
}
);
我找到了这个问题的解决方案,以防有人感兴趣。
与其尝试直接访问父级,不如创建查询可以继承的 class 。在这种情况下,我创建了一个统计数据 class,其中包含国家代码 属性。然后,属性 被填充到统计字段解析器中,并返回一个具有该值的 Statistics 类型的新对象。然后我可以通过查看 context.Source.Country 从子查询访问国家代码,然后我只是不将国家 属性 映射到子查询中的字段,因为我是没兴趣暴露它。
以下是 SUNMO 的回答示例以及一些描述性评论:
// This is an internal object whose properties don't necessarily need to be
// exposed as GraphQL fields. It's purpose is to propagate arguments or some
// partially resolved data which can be further resolved in a child GraphType.
public class Statistics
{
public string CompanyId { get; set; }
public string Country { get; set; }
}
// This is the root GraphQL Query class.
public class MyQuery : ObjectGraphType
{
private const string CompanyIdArgumentName = "companyId";
private const string CountryArgumentName = "country";
public MyQuery()
{
Field<CompanyStatisticsType>(
name: "statistics",
arguments: new QueryArguments(
new QueryArgument<StringGraphType> { Name = CompanyIdArgumentName },
new QueryArgument<StringGraphType> { Name = CountryArgumentName }
),
resolve: context => {
return new Statistics
{
CompanyId = context.GetArgument<string>(CompanyIdArgumentName),
Country = context.GetArgument<string>(CountryArgumentName)
};
}
// In the above `resolve` implementation, we're passing the value
// of the arguments to the a new Statistics object which will be
// CompanyStatisticsType's context.Source
);
}
}
public class CompanyStatisticsType : ObjectGraphType<Statistics>
{
public CompanyStatisticsType()
{
Field<IntGraphType>(
name: "completeInvoicesCount",
resolve: context => {
return GetCompletedInvoicesCount(
companyId: context.Source.CompanyId,
country: context.Source.Country
// Above we are using context.Source, which is an
// instance of the `Statistics` class.
);
}
);
Field(statistics => statistics.Country);
// Notice how we expose the above `country` field but not `companyId`,
// further demonstrating that not every property on the `Statistics`
// class needs to be exposed as a GraphQL field.
}
}
我有一个字段 "statistics" 的查询,它是一个具有三个不同累加值的子查询。我希望能够为统计数据提供国家/地区参数,然后在子查询中不同字段的解析器中访问该参数。
我正在使用 GraphQL.Server.Transports.AspNetCore nuget 包。子查询使用 IDependencyResolver 解析,因为它对不同字段的解析器中使用的服务有一些依赖性。
我尝试通过 ResolveFieldContext 访问父级,但它似乎不可用。在名为 "Source" 的上下文中有一个 属性,但它指的是子查询对象。
如果我们查看 GraphQL 的其他实现,似乎应该是可能的,但我不知道如何从 ASP.NET Core
获得结果下面的代码显示了名为 "CompanyGroupQuery"
的主查询的一部分Field<CompanyStatisticsQuery>(
"statistics",
arguments: new QueryArguments(new QueryArgument<StringGraphType> { Name = "country" }),
resolve: context => resolver.Resolve<CompanyStatisticsQuery>()
);
子查询看起来像这样
Field<IntGraphType>(
"completeInvoicesCount",
resolve: context => {
// This is to show what I'm trying to achieve
var parent = context.Parent;
var companyId = context.GetArgument<string>("companyId");
var country = context.GetArgument<string>("country");
return null;
}
);
我找到了这个问题的解决方案,以防有人感兴趣。 与其尝试直接访问父级,不如创建查询可以继承的 class 。在这种情况下,我创建了一个统计数据 class,其中包含国家代码 属性。然后,属性 被填充到统计字段解析器中,并返回一个具有该值的 Statistics 类型的新对象。然后我可以通过查看 context.Source.Country 从子查询访问国家代码,然后我只是不将国家 属性 映射到子查询中的字段,因为我是没兴趣暴露它。
以下是 SUNMO 的回答示例以及一些描述性评论:
// This is an internal object whose properties don't necessarily need to be
// exposed as GraphQL fields. It's purpose is to propagate arguments or some
// partially resolved data which can be further resolved in a child GraphType.
public class Statistics
{
public string CompanyId { get; set; }
public string Country { get; set; }
}
// This is the root GraphQL Query class.
public class MyQuery : ObjectGraphType
{
private const string CompanyIdArgumentName = "companyId";
private const string CountryArgumentName = "country";
public MyQuery()
{
Field<CompanyStatisticsType>(
name: "statistics",
arguments: new QueryArguments(
new QueryArgument<StringGraphType> { Name = CompanyIdArgumentName },
new QueryArgument<StringGraphType> { Name = CountryArgumentName }
),
resolve: context => {
return new Statistics
{
CompanyId = context.GetArgument<string>(CompanyIdArgumentName),
Country = context.GetArgument<string>(CountryArgumentName)
};
}
// In the above `resolve` implementation, we're passing the value
// of the arguments to the a new Statistics object which will be
// CompanyStatisticsType's context.Source
);
}
}
public class CompanyStatisticsType : ObjectGraphType<Statistics>
{
public CompanyStatisticsType()
{
Field<IntGraphType>(
name: "completeInvoicesCount",
resolve: context => {
return GetCompletedInvoicesCount(
companyId: context.Source.CompanyId,
country: context.Source.Country
// Above we are using context.Source, which is an
// instance of the `Statistics` class.
);
}
);
Field(statistics => statistics.Country);
// Notice how we expose the above `country` field but not `companyId`,
// further demonstrating that not every property on the `Statistics`
// class needs to be exposed as a GraphQL field.
}
}