У меня есть простое перечисление, которое я пытаюсь включить в свой тип GraphQL, и получаю следующую ошибку:
The GraphQL type for Field: 'Category' on parent type: 'NewsItemType' could not be derived implicitly.
------------------The GraphQL type for Field: 'Category' on parent type: 'NewsItemType' could not be derived implicitly.
---------------The type: NewsType cannot be coerced effectively to a GraphQL type Parameter name: type
мое простое перечисление выглядит так:
public enum NewsType
{
General = 0,
Business = 1,
Entertainment = 2,
Sports = 3,
Technology = 4
}
GraphQL ObjectGraphType, в который он включен:
public class NewsItemType : ObjectGraphType<NewsItemViewModel>
{
public NewsItemType()
{
Field(x => x.Id).Description("Id of a news item.");
Field(x => x.Title).Description("Title of a new item.");
Field(x => x.Description).Description("Description of a news item.");
Field(x => x.Author).Description("Author of a news item.");
Field(x => x.Url).Description("URI location of the news item");
Field(x => x.ImageUrl).Description("URI location of the image for the news item");
Field(x => x.PublishDate).Description("Date the news item was published");
Field(x => x.Category).Description("Category of the news item.");
}
}
и, наконец, модель представления, на которой основан тип graphql:
public class NewsItemViewModel : ViewModelBase
{
public string Title { get; set; }
public string Author { get; set; }
public string Description { get; set; }
public string Url { get; set; }
public string ImageUrl { get; set; }
public DateTime PublishDate { get; set; }
public NewsType Category { get; set; }
}
Что я делаю неправильно здесь и как я могу это преодолеть?
Обновлено: мой запрос содержит следующее:
Field<ListGraphType<NewsItemType>>(
name: "newsItems",
arguments: new QueryArguments(
new QueryArgument<IntGraphType>() { Name = "count" },
new QueryArgument<IntGraphType>() { Name = "category" }),
resolve: context =>
{
var count = context.GetArgument<int?>("count");
var category = context.GetArgument<int>("category");
var newsType = (NewsType)category;
if (count.HasValue)
{
return newsItemService.GetMostRecent(newsType, count.Value);
}
else
{
return newsItemService.GetMostRecent(newsType);
}
}
)





Вот быстрый способ сделать это для вашего случая. По сути, вы не используете лямбда-выражение по умолчанию Field. Вместо этого на самом деле напишите распознаватель самостоятельно и преобразуйте перечисление в правильный тип. Это помогает GraphQL правильно преобразовать тип в тип, который вы хотите вернуть.
Field<IntGraphType>("category", resolve: context => (int)context.Source.Category);
Если бы ваше перечисление было строкой, вы могли бы сделать то же самое и для этого.
Field<StringGraphType>("category", resolve: context => context.Source.Category.ToString());
Существует еще один, более подробный способ, описанный в этом ответе, когда вы сначала наследуете от EnumerationGraphType<T>, а затем выполняете тот же пользовательский преобразователь, что и выше.
Мне тоже было очень трудно заставить это работать. Официальной документации определенно не хватает в этом отношении. То, как я заставил его работать, было основано на том, что я нашел в эта статья.
Для вашего сценария вы должны создать класс GraphType для вашего перечисления следующим образом:
public class NewsEnumType : EnumerationGraphType<NewsType>
{
}
Затем обновите свое поле до:
Field<NewsEnumType>(nameof(NewsItemViewModel.Category)).Description("Category of the news item.");
Следует упомянуть еще одну вещь, с которой я столкнулся с EnumTypes, чего не ожидал. Если вы используете перечисление в качестве параметра, сделайте то, что вы делали выше, когда вы принимаете его как IntGraphType, а затем приводите к своему типу перечисления (NewsType)category
Field<ListGraphType<NewsItemType>>(
name: "newsItems",
arguments: new QueryArguments(
new QueryArgument<IntGraphType>() { Name = "count" },
new QueryArgument<IntGraphType>() { Name = "category" }),
resolve: context =>
{
var count = context.GetArgument<int?>("count");
var category = context.GetArgument<int>("category");
var newsType = (NewsType)category;
if (count.HasValue)
{
return newsItemService.GetMostRecent(newsType, count.Value);
}
else
{
return newsItemService.GetMostRecent(newsType);
}
}
)
Мое перечисление было частью сложного объекта, который я передал в качестве параметра, больше похожего на new QueryArgument<NewsItemType>() { Name = "newsItem" },
Если вы собираетесь это сделать, то свойство category объекта, переданного на сервер, должно быть строкой. Итак, если категория, которую вы передаете обратно на сервер, — Business = 1, то вам нужно передать category: 'Business', а НЕ category: 1.
Спасибо за ответ. Я тоже столкнулся с этим. Это разочаровывает, потому что в документации GraphQL .NET прямо указано, что в этом случае должен работать «синтаксис выражения». Может быть, это ошибка?