我是 GraphQL 的新手。
当前,我有一个查询定义,用于搜索学生及其参加的班:
var studentsQueryArguments = new QueryArguments();
studentsQueryArguments.Add(new QueryArgument<ListGraphType<IntGraphType>> { Name = "ids", Description = "Student indexes." });
studentsQueryArguments.Add(new QueryArgument<RangeModelType<double?, double?>> {Name = "age", Description = "Age range of student."});
Field<ListGraphType<StudentType>>(
"students",
arguments: studentsQueryArguments,
resolve: context =>
{
var students = relationalDbContext.Students.AsQueryable();
var classes = relationalDbContext.Classes.AsQueryable();
var participatedClasses = relationalDbContext.StudentInClasses.AsQueryable();
var ids = context.GetArgument<List<int>>("ids");
var age = context.GetArgument<RangeModel<double?, double?>>("age");
if (ids != null)
students = students.Where(x => ids.Contains(x.Id));
if (age != null)
{
var from = age.From;
var to = age.To;
if (from != null)
students = students.Where(x => x.Age >= from);
if (to != null)
students = students.Where(x => x.Age <= to);
}
var results = (from student in students
select new StudentViewModel
{
Id = student.Id,
Age = student.Age,
FullName = student.FullName,
Photo = student.Photo,
Classes = from participatedClass in participatedClasses
from oClass in classes
where participatedClass.StudentId == student.Id &&
participatedClass.ClassId == oClass.Id
select new ClassViewModel
{
Id = oClass.Id,
ClosingHour = oClass.ClosingHour,
Name = oClass.Name,
OpeningHour = oClass.OpeningHour
}
});
return results;
});
在上面的代码中,我加入了学生和班级。 使用查询
{
students(ids: [1, 2, 3]) {
id
age
classes {
name
openingHour
closingHour
}
}
}
返回学生及其班。没关系。
我想要的是当我使用此查询时:
{
students(ids: [1, 2, 3]) {
id
age
}
}
我的应用程序不会加入学生和班级,而只返回学生信息。
有可能吗?
谢谢
答案 0 :(得分:0)
我做了一个超酷的扩展方法,该方法返回所选内容是否包含在GraphQL查询中。 如果选择中存在导航属性,则将其包含在查询中。
using System;
using System.Linq;
using GraphQL.Language.AST;
using GraphQL.Types;
public static class ContextExtensions
{
/// <summary>
/// Returns true if the given fieldSelector exists in the selection of the query.
/// </summary>
/// <param name="context">The working context</param>
/// <param name="fieldSelector">The query of the field selector. For example items:organizationUnits:displayName</param>
/// <param name="namespaceSeperator">The seperator character of the fieldSelector. Default is :</param>
/// <returns></returns>
public static bool HasSelectionField(this ResolveFieldContext<object> context, string fieldSelector, char namespaceSeperator = ':')
{
if (string.IsNullOrWhiteSpace(fieldSelector))
{
return false;
}
if (context.SubFields == null)
{
return false;
}
var fragments = fieldSelector.Split(new[] { namespaceSeperator }, StringSplitOptions.RemoveEmptyEntries);
if (fragments.Length == 1)
{
return context.SubFields.ContainsKey(fragments[0]);
}
if (context.SubFields[fragments[0]] == null)
{
return false;
}
if (context.SubFields[fragments[0]].SelectionSet == null)
{
return false;
}
if (context.SubFields[fragments[0]].SelectionSet.Selections == null)
{
return false;
}
var selections = context.SubFields[fragments[0]].SelectionSet.Selections;
for (var i = 1; i < fragments.Length; i++)
{
if (selections == null)
{
return false;
}
var field = selections.Select(selection => (Field)selection).FirstOrDefault(f => f.Name == fragments[i]);
if (field == null)
{
return false;
}
if (i == fragments.Length - 1)
{
return true;
}
selections = field.SelectionSet?.Selections;
}
return true;
}
}
protected override async Task<PagedResultDto<UserDto>> Resolve(ResolveFieldContext<object> context)
{
var total_count_exists = context.HasSelectionField("totalCount"); //true
var items_name_exists = context.HasSelectionField("items:name"); //true
var items_roles_name_exists = context.HasSelectionField("items:roles:name"); //true
var items_organizationUnits_displayName_exists = context.HasSelectionField("items:organizationUnits:displayName"); //true
var items_organizationUnits_xyz_exists = context.HasSelectionField("items:organizationUnits:xyz"); //false
}
query MyQuery {
users(id: 1) {
totalCount
items {
name
surname
roles {
id
name
displayName
}
organizationUnits {
id
code
displayName
}
}
}
}