在C#中使用graphql的嵌套查询

时间:2018-12-18 10:04:49

标签: 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;
            });

1 个答案:

答案 0 :(得分:0)

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之间,其中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
                }
            }
        }
    }
}