ASP.NET Core中能否创建GraphQL泛型类型?分页类型报错求助
问题分析与解决方案
你遇到的错误核心有两个关键点:
- 泛型继承方向错误:你的
PagedResultType<T>继承自ObjectGraphType<T>,但这个类型应该用来表示分页结果对象,而不是单个的业务实体/DTO。也就是说,它应该映射的是包含分页元数据(CurrentPage、PageCount等)和结果列表的那个类,而不是T本身。 - 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
相关产品推荐
相关产品推荐

