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

ASP.NET Core中能否创建GraphQL泛型类型?分页类型报错求助

问题分析与解决方案

你遇到的错误核心有两个关键点:

  1. 泛型继承方向错误:你的PagedResultType<T>继承自ObjectGraphType<T>,但这个类型应该用来表示分页结果对象,而不是单个的业务实体/DTO。也就是说,它应该映射的是包含分页元数据(CurrentPage、PageCount等)和结果列表的那个类,而不是T本身。
  2. ListGraphType的类型约束:ListGraphType<T>要求泛型参数T必须实现IGraphType(也就是GraphQL的类型定义),但你传入的是业务DTO类型(比如ComplaintSourceDTO),它并不属于GraphQL类型体系,所以编译器会报错。

下面是具体的修复步骤:

步骤1:确保你有一个分页结果业务模型

首先,确认你的项目中有一个用来承载分页数据的通用类,比如:

public class PagedResult<T>
{
    public int CurrentPage { get; set; }
    public int PageCount { get; set; }
    public int PageSize { get; set; }
    public int RowCount { get; set; }
    public int FirstRowOnPage { get; set; }
    public int LastRowOnPage { get; set; }
    public List<T> Results { get; set; }
}

这个类是业务层用来返回分页数据的载体,你的complaintSourceService.GetDataWithPaged方法应该返回的就是这个类型的实例。

步骤2:重构泛型分页GraphQL类型

我们需要创建一个泛型的GraphQL类型,用来映射上面的PagedResult<T>。这里我们使用双泛型参数:一个是业务模型类型(TModel),另一个是对应的GraphQL类型(TGraphType),这样可以明确指定结果列表对应的GraphQL类型:

using GraphQL.Types;

namespace WebApi.Data.Entities.Graphql.GraphQueryTypes
{
    // TModel:业务/DTO类型;TGraphType:对应的GraphQL对象类型,必须继承自ObjectGraphType<TModel>
    public class PagedResultType<TModel, TGraphType> : ObjectGraphType<PagedResult<TModel>> 
        where TGraphType : ObjectGraphType<TModel>, new()
    {
        public PagedResultType()
        {
            // 自动生成有意义的类型名称,比如PagedComplaintSourceDTOType
            Name = $"Paged{typeof(TGraphType).Name}";

            // 映射分页元数据字段
            Field(x => x.CurrentPage, description: "当前页码");
            Field(x => x.PageCount, description: "总页数");
            Field(x => x.PageSize, description: "每页条数");
            Field(x => x.RowCount, description: "总记录数");
            Field(x => x.FirstRowOnPage, description: "当前页第一条记录的序号");
            Field(x => x.LastRowOnPage, description: "当前页最后一条记录的序号");

            // 映射结果列表,使用指定的GraphQL类型包装
            Field<ListGraphType<TGraphType>>(
                "results",
                description: "当前页的结果列表",
                resolve: context => context.Source.Results
            );
        }
    }
}

步骤3:确保你有业务DTO对应的GraphQL类型

你需要为ComplaintSourceDTO创建对应的GraphQL对象类型,比如:

public class ComplaintSourceDTOType : ObjectGraphType<ComplaintSourceDTO>
{
    public ComplaintSourceDTOType()
    {
        // 映射DTO的字段,示例:
        Field(x => x.Id);
        Field(x => x.Name);
        // 其他字段...
    }
}

步骤4:在RootQuery中使用分页类型

现在你可以在RootQuery中正确注册这个分页字段了:

Field<PagedResultType<ComplaintSourceDTO, ComplaintSourceDTOType>>(
    "complaintSourceTypes",
    arguments: new QueryArguments(
        new QueryArgument<IntGraphType> { Name = "page", Description = "Sayfalama için sayfa " },
        new QueryArgument<IntGraphType> { Name = "pageSize", Description = "Sayfalama için gerekli sayfa sayısı" }
    ),
    resolve: context => complaintSourceService.GetDataWithPaged(
        context.GetArgument<int>("page"), 
        context.GetArgument<int>("pageSize"))
);

额外说明:如果想简化泛型参数

如果你觉得双泛型参数太繁琐,可以通过反射的方式自动创建对应的ListGraphType,但这种方式可读性稍差,示例如下(不推荐,除非有特殊需求):

public class PagedResultType<TModel> : ObjectGraphType<PagedResult<TModel>>
{
    public PagedResultType(Type graphType)
    {
        Name = $"Paged{graphType.Name}";

        // 映射分页元数据字段...

        // 通过反射创建ListGraphType
        var listGraphType = typeof(ListGraphType<>).MakeGenericType(graphType);
        Field(listGraphType, "results", resolve: context => context.Source.Results);
    }
}

使用时需要手动传入GraphQL类型:

Field(new PagedResultType<ComplaintSourceDTO>(typeof(ComplaintSourceDTOType)), "complaintSourceTypes", ...);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:03:00