【问题标题】:Nested queries with graphql in c#c#中使用graphql的嵌套查询
【发布时间】:2020-12-14 21:03:35
【问题描述】:

我正在尝试在 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;
            });

【问题讨论】:

  • 究竟是什么不在这里工作?
  • 查询有效,但我只能查询根,我不能查询子实体,例如 Airport(id: 1){ Plane(id:1)} ,我只能查询机场,不能添加平面子查询
  • 但是出现错误无法查询?还是图表设置不正确?
  • 我认为设置不正确
  • 从上面的代码很难看出,但我的项目中有一些类似的代码。我不像你那样设置图表,我使用类似Field&lt;ListGraphType&lt;PlaneType&gt;&gt;("Plane", "Aiports Planes");的代码。你的架构看起来好吗?

标签: c# graphql


【解决方案1】:

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 Query 类还必须扩展 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
                }
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-29
    • 2020-12-02
    • 1970-01-01
    • 2020-01-29
    • 2018-06-13
    • 2019-05-30
    • 2021-01-14
    • 2017-06-16
    相关资源
    最近更新 更多