【发布时间】:2021-12-25 09:02:39
【问题描述】:
我正在学习如何在 asp.net core 5 项目中编写 GraphQL。我正在使用 Hot Chocolate v5,执行以下查询时出错:
query
{
platform
{
id
name,
commands
{
id
howTo
commandLine
}
}
}
执行此查询时出现以下错误:
{
“错误”:[
{
"message": "在 commands 字段中找不到名称为 platform 的参数。",
“地点”:[
{
“行”:7,
“列”:5
}
],
“小路”: [
“平台”,
4、
“命令”
],
“扩展”:{
"fieldName": "命令",
“参数名称”:“平台”
}
}, ...
如果我在以下查询中执行查询,那么它的工作原理:
query
{
platform
{
id
name
}
}
query
{
command
{
id
howTo
commandLine
}
}
我认为与此错误相关的代码片段是:
public class Command
{
/// <summary>
/// Represents the unique ID for the command.
/// </summary>
[Key]
public int Id { get; set; }
/// <summary>
/// Represents the how-to for the command.
/// </summary>
[Required]
public string HowTo { get; set; }
/// <summary>
/// Represents the command line.
/// </summary>
[Required]
public string CommandLine { get; set; }
/// <summary>
/// Represents the unique ID of the platform which the command belongs.
/// </summary>
[Required]
public int PlatformId { get; set; }
/// <summary>
/// This is the platform to which the command belongs.
/// </summary>
public Platform Platform { get; set; }
}
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions options) : base(options)
{
}
public DbSet<Platform> Platforms { get; set; }
public DbSet<Command> Commands { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Platform>()
.HasMany(x => x.Commands)
.WithOne(x => x.Platform!)
.HasForeignKey(x => x.PlatformId);
builder.Entity<Command>()
.HasOne(x => x.Platform)
.WithMany(x => x.Commands)
.HasForeignKey(x => x.PlatformId);
}
}
[GraphQLDescription("Represents the queries available.")]
public class Query
{
/// <summary>
/// Gets the queryable <see cref="Command"/>.
/// </summary>
/// <param name="context">The <see cref="AppDbContext"/>.</param>
/// <returns>The queryable <see cref="Command"/>.</returns>
[UseDbContext(typeof(AppDbContext))]
[UseFiltering]
[UseSorting]
[GraphQLDescription("Gets the queryable command.")]
public IQueryable<Command> GetCommand([ScopedService] AppDbContext context)
{
return context.Commands;
}
/// <summary>
/// Gets the queryable <see cref="Platform"/>.
/// </summary>
/// <param name="context">The <see cref="AppDbContext"/>.</param>
/// <returns>The queryable <see cref="Platform"/>.</returns>
[UseDbContext(typeof(AppDbContext))]
[UseFiltering]
[UseSorting]
[GraphQLDescription("Gets the queryable platform.")]
public IQueryable<Platform> GetPlatform([ScopedService] AppDbContext context)
{
return context.Platforms;
}
public class PlatformType : ObjectType<Platform>
{
protected override void Configure(IObjectTypeDescriptor<Platform> descriptor)
{
descriptor.Description("Represents any software or service that has a command line interface.");
descriptor.Field(p => p.Id)
.Description("Represents the unique ID for the platform.");
descriptor.Field(p => p.Name)
.Description("Represents the name for the platform.");
descriptor.Field(p => p.LicenceKey)
.Ignore();
descriptor.Field(p => p.Commands)
.ResolveWith<Resolvers>(p => p.GetCommands(default!, default!))
.UseDbContext<AppDbContext>()
.Description("This is the list of available commands for this platform.");
}
private class Resolvers
{
public IQueryable<Command> GetCommands(Platform platform, [ScopedService] AppDbContext context)
{
return context.Commands.Where(p => p.PlatformId == platform.Id);
}
}
public class CommandType : ObjectType<Command>
{
protected override void Configure(IObjectTypeDescriptor<Command> descriptor)
{
descriptor.Description("Represents any executable command.");
descriptor.Field(c => c.Id)
.Description("Represents the unique ID for the command.");
descriptor.Field(c => c.HowTo)
.Description("Represents the how-to for the command.");
descriptor.Field(c => c.CommandLine)
.Description("Represents the command line.");
descriptor.Field(c => c.PlatformId)
.Description("Represents the unique ID of the platform which the command belongs.");
descriptor.Field(c => c.Platform)
.ResolveWith<Resolvers>(c => c.GetPlatform(default!, default!))
.UseDbContext<AppDbContext>()
.Description("This is the platform to which the command belongs.");
}
private class Resolvers
{
public Platform GetPlatform(Command command, [ScopedService] AppDbContext context)
{
return context.Platforms.FirstOrDefault(p => p.Id == command.PlatformId);
}
}
public class Startup
{
private IConfiguration Configuration { get; }
public Startup(IConfiguration collection)
{
Configuration = collection;
}
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.ConfigureDbContext(Configuration);
services.ConfigureGraphQL();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseWebSockets();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGraphQL();
});
app.ConfigureGraphQL();
}
public static class ContexConfiguration
{
public static void ConfigureDbContext(this IServiceCollection services, IConfiguration configuration)
{
services.AddPooledDbContextFactory<AppDbContext>(options =>
options.UseSqlServer(configuration.GetConnectionString("DefaultConnection")));
}
}
public static class GraphQLConfiguration
{
/// <summary>
/// Configuration of the GrapQL server
/// </summary>
/// <param name="services"></param>
public static void ConfigureGraphQL(this IServiceCollection services)
{
services.AddGraphQLServer()
.AddQueryType<Query>()
.AddMutationType<Mutation>()
.AddSubscriptionType<Subscription>()
.AddType<PlatformType>()
.AddType<AddPlatformInputType>()
.AddType<AddPlatformPayloadType>()
.AddType<CommandType>()
.AddType<AddCommandInputType>()
.AddType<AddCommandPayloadType>()
.AddFiltering()
.AddSorting()
.AddInMemorySubscriptions();
}
/// <summary>
/// GraphQL Voyager UI configuration
/// </summary>
/// <param name="app"></param>
public static void ConfigureGraphQL(this IApplicationBuilder app)
{
app.UseGraphQLVoyager(
options: new VoyagerOptions()
{
GraphQLEndPoint = "/graphql"
},
path: "/graphql-voyager"
);
}
}
【问题讨论】:
标签: c# asp.net-core graphql hotchocolate