系列导航

使用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项目,调用接口:

可以看到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操作,所以能得到我们希望的结果。

总结

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

使用Hot Chocolate和.NET 6构建GraphQL应用(4) —— 实现Query映射功能的更多相关文章

  1. 使用Hot Chocolate和.NET 6构建GraphQL应用(3) —— 实现Query基础功能

    系列导航 使用Hot Chocolate和.NET 6构建GraphQL应用文章索引 需求 在本文中,我们通过一个简单的例子来看一下如何实现一个最简单的GraphQL的接口. 实现 引入Hot Cho ...

  2. 使用Hot Chocolate和.NET 6构建GraphQL应用(5) —— 实现Query过滤功能

    系列导航 使用Hot Chocolate和.NET 6构建GraphQL应用文章索引 需求 对于查询来说,还有一大需求是针对查询的数据进行过滤,本篇文章我们准备实现GraphQL中基本的查询过滤. 思 ...

  3. 使用Hot Chocolate和.NET 6构建GraphQL应用(6) —— 实现Query排序功能

    系列导航 使用Hot Chocolate和.NET 6构建GraphQL应用文章索引 需求 从前几篇文章可以看出,使用Hot Chocolate实现GraphQL接口是比较简单的,本篇文章我们继续查询 ...

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

    系列导航 使用Hot Chocolate和.NET 6构建GraphQL应用文章索引 需求 GraphQL中的查询分页相对来说是查询中比较难理解的,接口的Schema也和其他不一样.在这篇文章中,我们 ...

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

    系列背景 在进入微服务的实践系列之前,我们一起来学习和实践一下.NET应用开发生态中一些比较重要的技术,这个系列就是关于GraphQL在.NET 6应用中的实现. 系列导航 使用Hot Chocola ...

  6. 使用Hot Chocolate和.NET 6构建GraphQL应用(1)——GraphQL及示例项目介绍

    系列导航 使用Hot Chocolate和.NET 6构建GraphQL应用文章索引 前言 这篇文章是这个系列的第一篇,我们会简单地讨论一下GraphQL,然后介绍一下这个系列将会使用的示例项目. 关 ...

  7. 使用Hot Chocolate和.NET 6构建GraphQL应用(2) —— 实体相关功能实现

    系列导航 使用Hot Chocolate和.NET 6构建GraphQL应用文章索引 需求 在本文中,我们将会准备好用于实现GraphQL接口所依赖的底层数据,为下一篇文章具体实现GraphQL接口做 ...

  8. 使用Hot Chocolate和.NET 6构建GraphQL应用(8) —— 实现Mutate添加数据

    系列导航 使用Hot Chocolate和.NET 6构建GraphQL应用文章索引 需求 在讨论完GraphQL中的查询需求后,这篇文章我们将演示如何实现GraphQL中的数据添加任务. 思路 在G ...

  9. 使用Hot Chocolate和.NET 6构建GraphQL应用(9) —— 实现Mutate更新数据

    系列导航 使用Hot Chocolate和.NET 6构建GraphQL应用文章索引 需求 在上一篇文章中,我们演示了如何使用Hot Chocolate进行GraphQL的Mutate新增数据,这篇文 ...

随机推荐

  1. 【LeetCode】951. Flip Equivalent Binary Trees 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcod ...

  2. 【剑指Offer】调整数组顺序使奇数位于偶数前面 解题报告(Python)

    [牛客网]调整数组顺序使奇数位于偶数前面 解题报告 标签(空格分隔): 牛客网 题目地址:https://www.nowcoder.com/questionTerminal/beb5aa231adc4 ...

  3. 「实用」打造自我感觉非常漂亮的Mac终端

    背景 (今天我是一个美妆博主) 突然发现自己使用的iterm2终端样式有些朴素,为了让她看起来花枝招展的,我决定给她打扮打扮.毕竟每天面对她的时间比对象还多-- 效果对比 因为每个人的喜好都不一样,所 ...

  4. 编写Java程序,根据提供的 IP 地址,获取主机名称和域名

    查看本章节 查看作业目录 需求说明: 根据提供的 IP 地址,获取主机名称和域名 实现思路: 创建 GetHostNameByIpAddress 类,在main方法中声明 String 类型的变量 i ...

  5. js tab栏切换

    <!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" ...

  6. Django在使用logging日志模块时报错无法操作文件 logging error Permission Error [WinError 32]

    产生原因: 这个问题只会在开发的时候遇到,而且配置是写入到setting.py配置文件,我们定义了日志文件大小,当日志满了的时候,这时候就会遇到这个问题, 因为在使用Pycharm运行django的时 ...

  7. Pytest_参数化(10)

    pytest参数化有两种方式: mark的parametrize标记:@pytest.mark.parametrize(变量名,变量值),其中变量值类型为列表.元组或其它可迭代对象. fixture的 ...

  8. django中写入数据时给密码加密

    方法一.在自定义的form表单中重写save方法: 方法二.使用信号量来实现 1. 在应用的模块下新建signal.py文件 2.编写回调函数,内容如下: 3. 在应用的app.py文件中的ready ...

  9. mybatis学习笔记(三)

    使用mapper接口来实现数据操作 创建UserMapper接口,添加方法,方法名要与UserMappper.xml中id所一致并且接口名要与编写sql语句的xmL文件名同名.namespace 中的 ...

  10. android 解决报错 installation failed with message Failed to finalize session : INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION: Failed parse during installPackageLI: Failed to read manifest from /xx/xx/xx.apk

    新工程启动报错 怎么办? 解决: 将这个选项去掉勾选后点击ok即可