You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GraphQL.NET中Field与FieldAsync的使用问题求助(.NET6+GraphQL7)

.NET 6 + GraphQL 7:FieldAsync使用问题解决方案

问题概述

使用.NET 6和GraphQL 7开发时,遇到两个核心问题:

  1. FieldAsync没有ResolveScopedAsync方法,但业务需要该方法的依赖注入能力;
  2. 尝试用FieldAsync的.Arguments()批量添加参数时,报错'It is not possible using as method the not recallable member FieldType.Arguments'。
    而Field方法可正常调用ResolveScopedAsync并逐个添加参数。

可正常运行的Field代码

Field<QuizResultType, QuizResult>("userQuizResult")
    .Argument<NonNullGraphType<StringGraphType>>("postId")
    .Argument<NonNullGraphType<BooleanGraphType>>("status")
    .ResolveScopedAsync(async context =>
    {
        var user = await GetCurrentUser();
        var moduleId = context.GetArgument<int>("moduleId");
        var quizId = context.GetArgument<int>("quizId");
        var quizProgress = await unitOfWork.QuizProgressRepository.GetUserQuizProgressAsync(user.Id.ToString(), moduleId, quizId);
        return await moduleService.GetQuizResultAsync(quizProgress, quizId, moduleId);
    });

失败的FieldAsync尝试代码

FieldAsync<QuizResultType, QuizResult>("userQuizResult")
    .Arguments(new QueryArguments(
        new QueryArgument<NonNullGraphType<IntGraphType>> { Name = "moduleId" },
        new QueryArgument<NonNullGraphType<IntGraphType>> { Name = "quizId" }))

报错信息:'It is not possible using as method the not recallable member FieldType.Arguments',且FieldAsync无ResolveScopedAsync方法。


解决方案

问题1:FieldAsync无ResolveScopedAsync方法

GraphQL 7中,ResolveScopedAsync是**FieldBuilder<FieldType, TSource, TResult>的扩展方法,而FieldAsync返回的是FieldBuilder<FieldType, TResult>**,因此无法直接调用该方法。

有两种解决思路:

  1. 继续使用Field方法:这是最简单的方案,Field方法本身完全支持异步解析,ResolveScopedAsync可以正常使用,无需切换到FieldAsync;
  2. 改用ResolveAsync手动处理依赖:如果必须用FieldAsync,可以通过context.RequestServices获取依赖,替代ResolveScopedAsync的自动注入:
FieldAsync<QuizResultType, QuizResult>("userQuizResult")
    .Argument<NonNullGraphType<IntGraphType>>("moduleId")
    .Argument<NonNullGraphType<IntGraphType>>("quizId")
    .ResolveAsync(async context =>
    {
        // 从请求服务容器中获取所需实例
        var moduleService = context.RequestServices.GetRequiredService<IModuleService>();
        var unitOfWork = context.RequestServices.GetRequiredService<IUnitOfWork>();
        
        var user = await GetCurrentUser();
        var moduleId = context.GetArgument<int>("moduleId");
        var quizId = context.GetArgument<int>("quizId");
        var quizProgress = await unitOfWork.QuizProgressRepository.GetUserQuizProgressAsync(user.Id.ToString(), moduleId, quizId);
        return await moduleService.GetQuizResultAsync(quizProgress, quizId, moduleId);
    });

问题2:FieldAsync批量添加参数报错

FieldAsync返回的构建器不支持链式调用.Arguments()方法(因为Arguments是FieldType的属性,而非可链式调用的方法)。正确的参数添加方式有两种:

  1. 逐个调用.Argument()添加(推荐,和Field方法用法一致):
FieldAsync<QuizResultType, QuizResult>("userQuizResult")
    .Argument<NonNullGraphType<IntGraphType>>("moduleId")
    .Argument<NonNullGraphType<IntGraphType>>("quizId")
    // 后续添加ResolveAsync逻辑
  1. 通过FieldAsync的重载直接传入参数:
FieldAsync<QuizResultType, QuizResult>(
    name: "userQuizResult",
    arguments: new QueryArguments(
        new QueryArgument<NonNullGraphType<IntGraphType>> { Name = "moduleId" },
        new QueryArgument<NonNullGraphType<IntGraphType>> { Name = "quizId" }),
    resolve: async context =>
    {
        // 解析逻辑
    });

总结

  • 优先选择Field方法配合ResolveScopedAsync,既满足依赖注入需求,又保持代码简洁;
  • 若使用FieldAsync,通过.Argument()逐个添加参数,并在ResolveAsync中手动从请求服务获取依赖;
  • 避免在FieldAsync后链式调用.Arguments(),改用上述两种合法方式添加参数。

内容的提问来源于stack exchange,提问作者Raso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 05:36:36