使用Hot Chocolate和.NET 6构建GraphQL应用(4) —— 实现Query映射功能


系列导航

使用Hot Chocolate和.NET 6构建GraphQL应用文章索引

需求

在上一篇文章使用Hot Chocolate和.NET 6构建GraphQL应用(3) —— 实现Query基础功能中,我们留了两个问题,一是通过GraphQL接口返回的Posts结果并没有获取到关联的Comment和Tag内容,二是返回结果没有进行排序。在这篇文章中,我们先来解决第一个问题。

思路

要获取关联实体,使用EF Core自然会想到在进行Query的时候添加一下Include语句就可以了,这种方式虽然可以实现,但是这其实并不太符合GraphQL接口的风格。GraphQL本身就是将数据对象作为图中的顶点以及其邻接点来看待的。所以我们不会修改接口本身的逻辑,通过Hot Chocolate为我们提供的映射(Projection)属性来完成需求。

实现

要使用Projection属性,需要先在添加服务依赖注入的时候指定:

  • ProgramExtension.cs
builder.Services
    .AddGraphQLServer()
    .AddProjections()
    .AddQueryType<Query>()
    .AddType<PostType>();

然后在接口上方添加UseProjection即可:

  • Query.cs
[UseProjection]
public IQueryable<Post> GetPosts([Service] IRepository<Post> repository) => repository.GetAsQueryable();

这样就实现了关联实体的获取,非常简单,下面我们来验证一下。

验证

启动Api项目,调用接口:

img

可以看到Comment和Tag信息已经出现在返回体中了,我们再来看一下控制台输出的EF Core日志:

[09:48:40 INF] Executing endpoint 'Hot Chocolate GraphQL Pipeline'
[09:48:40 WRN] Compiling a query which loads related collections for more than one collection navigation, either via 'Include' or through projection, but no 'QuerySplittingBehavior' has been configured. By default, Entity Framework will use 'QuerySplittingBehavior.SingleQuery', which can potentially result in slow query performance. See https://go.microsoft.com/fwlink/?linkid=2134277 for more information. To identify the query that's triggering this warning call 'ConfigureWarnings(w => w.Throw(RelationalEventId.MultipleCollectionIncludeWarning))'.
[09:48:40 INF] Executed DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT "p"."Id", "p"."Title", "p"."Author", "c"."Content", "c"."Id", "t0"."Name", "t0"."PostsId", "t0"."TagsId", "t0"."Id"
FROM "Posts" AS "p"
LEFT JOIN "Comments" AS "c" ON "p"."Id" = "c"."PostId"
LEFT JOIN (
    SELECT "t"."Name", "p0"."PostsId", "p0"."TagsId", "t"."Id"
    FROM "PostTag" AS "p0"
    INNER JOIN "Tags" AS "t" ON "p0"."TagsId" = "t"."Id"
) AS "t0" ON "p"."Id" = "t0"."PostsId"
ORDER BY "p"."Id", "c"."Id", "t0"."PostsId", "t0"."TagsId"
[09:48:40 INF] Executed endpoint 'Hot Chocolate GraphQL Pipeline'

从日志中可以看到Hot Chocolate告诉我们加载多个关联实体集合的时候要么通过Include方式,要么使用Projection,但是在没有应用任何QuerySplittingBehavior的情况下,会默认使用QuerySplittingBehavior.SingleQuery方式,可能会导致慢查询,具体的说明也给出了链接,有兴趣的小伙伴可以看一下。

然后就是实际执行的SQL语句了,可以看到这次的SQL语句明显进行了关联对象之间的Join操作,所以能得到我们希望的结果。

总结

在本文中我们实现了关联对象的获取,下一篇文章将会介绍如何进行查询数据的过滤。

版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
管理员
上一篇:Nuget包增加输出目录targets配置
下一篇:中国式浪漫,二十四节气倒计时去水印高清壁纸,承包你22年的桌面壁纸
评论列表

发表评论

评论内容
昵称:
关联文章

使用Hot Chocolate.NET 6构建GraphQL应用(4) —— 实现Query映射功能
使用Hot Chocolate.NET 6构建GraphQL应用(3) —— 实现Query基础功能
使用Hot Chocolate.NET 6构建GraphQL应用(2) —— 实体相关功能实现
使用Hot Chocolate.NET 6构建GraphQL应用(1)——GraphQL及示例项目介绍
使用.NET 6开发TodoList应用(31)——实现基于Github ActionsACI的CI/CD
使用.NET 6开发TodoList应用(14)——实现查询过滤
使用.NET 6开发TodoList应用(29)——实现静态字符串本地化功能
使用.NET 6开发TodoList应用(24)——实现基于JWT的Identity功能
使用.NET 6开发TodoList应用(30)——实现Docker打包部署
使用.NET 6开发TodoList应用(11)——使用FluentValidationMediatR实现接口请求验证
使用.NET 6开发TodoList应用(26)——实现ConfigurationOption的强类型绑定
使用.NET 6开发TodoList应用(15)——实现查询搜索
使用.NET 6开发TodoList应用(25)——实现RefreshToken
使用.NET 6开发TodoList应用(9)——实现PUT请求
使用.NET 6开发TodoList应用(22)——实现缓存
使用.NET 6开发TodoList应用(16)——实现查询排序
使用.NET 6开发TodoList应用(7)——使用AutoMapper实现GET请求
使用.NET 6开发TodoList应用(6)——使用MediatR实现POST请求
使用.NET 6开发TodoList应用(12)——实现ActionFilter
使用.NET 6开发TodoList应用(28)——实现应用程序健康检查

联系我们
联系电话:15090125178(微信同号)
电子邮箱:garson_zhang@163.com
站长微信二维码
微信二维码