c# - c#中使用graphql的嵌套查询
问题描述
我试图在 C# 中实现一个 graphql api。我有基本的工作,但我正在努力让嵌套查询工作。
我已经看到它在 NodeJS 和其他人中实现。我只是想知道是否有人可以帮助我在 c# 中实现相同的功能。
基本类型:
public AirportType()
{
Name = "Airport";
Field(x => x.Id, type: typeof(IdGraphType)).Description("The ID of the Airport.");
Field(x => x.Name).Description("The name of the Airport");
Field(x => x.Location).Description("The Location of the Airport");
Field(x => x.Plane,nullable:true, type: typeof(ListGraphType<PlaneType>)).Description("Aiports Planes");
}
public PlaneType()
{
Name = "Plane";
Field(x => x.Id, type: typeof(IdGraphType)).Description("The ID of the Plane.");
Field(x => x.Model).Description("The model of the Plane");
Field(x => x.Callsign).Description("The callsign of the Plane");
Field(x => x.AirportId,nullable:true).Description("The parent Aiport");
Field(x => x.Pilot,nullable:true, type: typeof(ListGraphType<PilotType>)).Description("The Planes Pilots");
}
public PilotType()
{
Name = "Pilot";
Field(x => x.Id, type: typeof(IdGraphType)).Description("The ID of the Pilot.");
Field(x => x.Name).Description("The name of the Pilot");
Field(x => x.Surname).Description("The surname of the Pilot");
Field(x => x.PlaneId,nullable: true).Description("The parent Plane");
}
和基本查询:
Field<AirportType>(
"airport",
arguments: new QueryArguments(
new QueryArgument<IdGraphType> { Name = "id", Description = "The ID of the aiport." }),
resolve: context =>
{
var id = context.GetArgument<int?>("id");
var airport = db.Airport.Include("Plane.Pilot").FirstOrDefault(i => i.Id == id);
return airport;
});
Field<ListGraphType<AirportType>>(
"airports",
resolve: context =>
{
var airports = db.Airport.Include("Plane.Pilot");
return airports;
});
Field<ListGraphType<PlaneType>>(
"planes",
resolve: context =>
{
var planes = db.Plane.Include("Pilot").Include("Airport");
return planes;
});
解决方案
AirportType、PilotType 和 PlaneType 需要扩展 ObjectGraphType<>
public class Airport
{
public IdGraphType Id { get; set; }
public string Name { get; set; }
public string Location { get; set; }
public PlaneType Plane { get; set; }
}
public class AirportType : ObjectGraphType<Airport>
{
public AirportType()
{
Name = "Airport";
Field(x => x.Id, type: typeof(IdGraphType)).Description("The ID of the Airport.");
Field(x => x.Name).Description("The name of the Airport");
Field(x => x.Location).Description("The Location of the Airport");
Field(x => x.Plane, nullable: true, type: typeof(ListGraphType<PlaneType>)).Description("Aiports Planes");
}
}
public class Pilot
{
public IdGraphType Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public IdGraphType PlaneId { get; set; }
}
public class PilotType : ObjectGraphType<Pilot>
{
public PilotType()
{
Name = "Pilot";
Field(x => x.Id, type: typeof(IdGraphType)).Description("The ID of the Pilot.");
Field(x => x.Name).Description("The name of the Pilot");
Field(x => x.Surname).Description("The surname of the Pilot");
Field(x => x.PlaneId, nullable: true).Description("The parent Plane");
}
}
public class Plane
{
public IdGraphType Id { get; set; }
public string Model { get; set; }
public string Callsign { get; set; }
public string AirportId { get; set; }
public PilotType Pilot { get; set; }
}
public class PlaneType : ObjectGraphType<Plane>
{
public PlaneType()
{
Name = "Plane";
Field(x => x.Id, type: typeof(IdGraphType)).Description("The ID of the Plane.");
Field(x => x.Model).Description("The model of the Plane");
Field(x => x.Callsign).Description("The callsign of the Plane");
Field(x => x.AirportId, nullable: true).Description("The parent Aiport");
Field(x => x.Pilot, nullable: true, type: typeof(ListGraphType<PilotType>)).Description("The Planes Pilots");
}
}
GraphQL 查询类还必须扩展 ObjectGraphType
public class MyQuery : ObjectGraphType
{
public MyQuery(IAirForceRepository db)
{
Field<AirportType>(
"airport",
arguments: new QueryArguments(
new QueryArgument<IdGraphType> { Name = "id", Description = "The ID of the airport." }),
resolve: context =>
{
var id = context.GetArgument<int?>("id");
var airport = db.Airport.Include("Plane.Pilot").FirstOrDefault(i => i.Id == id);
return airport;
});
Field<ListGraphType<AirportType>>(
"airports",
resolve: context =>
{
var airports = db.Airport.Include("Plane.Pilot");
return airports;
});
Field<ListGraphType<PlaneType>>(
"planes",
resolve: context =>
{
var planes = db.Plane.Include("Pilot").Include("Airport");
return planes;
});
}
}
为了查询子实体(例如 Plane 和 Pilot),您需要在两者之间添加一个 Connection。在这个例子中,在 Plane 和 Pilot 之间,Plane 是根,Pilot 是子实体,这两个类必须修改如下
修改平面类
public class Plane
{
public IdGraphType Id { get; set; }
public string Model { get; set; }
public string Callsign { get; set; }
public string AirportId { get; set; }
public PilotType Pilot { get; set; }
public Connection<Pilot> PilotConnection { get; set; }
public Plane()
{
PilotConnection = new Connection<Pilot>
{
TotalCount = 3,
PageInfo = new PageInfo
{
HasNextPage = false,
HasPreviousPage = false,
StartCursor = "0",
EndCursor = "2",
},
Edges = new List<Edge<Pilot>>
{
new Edge<Pilot> {Cursor = "0", Node = new Pilot { Name = "Johnny", Id = new IdGraphType() }},
new Edge<Pilot> {Cursor = "1", Node = new Pilot { Name = "Ronny", Id = new IdGraphType() }},
new Edge<Pilot> {Cursor = "2", Node = new Pilot {Name = "Jimmy", Id = new IdGraphType() }}
}
};
}
}
修改 PlaneType 类
public class PlaneType : ObjectGraphType<Plane>
{
public PlaneType()
{
Name = "Plane";
Field(x => x.Id, type: typeof(IdGraphType)).Description("The ID of the Plane.");
Field(x => x.Model).Description("The model of the Plane");
Field(x => x.Callsign).Description("The callsign of the Plane");
Field(x => x.AirportId, nullable: true).Description("The parent Aiport");
Field(x => x.Pilot, nullable: true, type: typeof(ListGraphType<PilotType>)).Description("The Planes Pilots");
Connection<PilotType>()
.Name("pilots")
.Description("Pilots that drive this plane")
.Resolve(context => context.Source.PilotConnection);
}
}
然后,您可以对与该子实体的连接执行查询,但无需为其提供参数(例如 id:"1"),如下例所示
query {
plane(id: "1"){
id
model
callsign
airportid
pilot {
edges {
node {
id
name
}
}
}
}
}
推荐阅读
- powerbi - 一列中每 22 个计数 1 - DAX
- bash - BASH - for 循环不在 while 循环内执行
- node.js - Mongodb聚合查找条件
- selenium-ide - 页面上是否有元素通过 IF 语句。硒 IDE
- xslt - 使用连续空白 xsl:text 时,从输出文件中抑制空白文本
- c - 未在客户端获取输出(C 中的 UDP 套接字)
- ansible - 将变量作为 import_playbook 变量传递
- html - 图像 src 未在剃刀视图中读取 base64 字符串
- amazon-web-services - 更新 ECS 集群中 Fargate 定时任务的任务定义
- numpy - 使用 Numpy 向量化的循环