GraphQL.NET, как добавить перечисление в тип GraphQL

У меня есть простое перечисление, которое я пытаюсь включить в свой тип 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);
                }
            }
        )
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
2 547
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вот быстрый способ сделать это для вашего случая. По сути, вы не используете лямбда-выражение по умолчанию Field. Вместо этого на самом деле напишите распознаватель самостоятельно и преобразуйте перечисление в правильный тип. Это помогает GraphQL правильно преобразовать тип в тип, который вы хотите вернуть.

Field<IntGraphType>("category", resolve: context => (int)context.Source.Category);

Если бы ваше перечисление было строкой, вы могли бы сделать то же самое и для этого.

Field<StringGraphType>("category", resolve: context => context.Source.Category.ToString());

Существует еще один, более подробный способ, описанный в этом ответе, когда вы сначала наследуете от EnumerationGraphType<T>, а затем выполняете тот же пользовательский преобразователь, что и выше.

https://stackoverflow.com/a/56051133/11842628

Ответ принят как подходящий

Мне тоже было очень трудно заставить это работать. Официальной документации определенно не хватает в этом отношении. То, как я заставил его работать, было основано на том, что я нашел в эта статья.

Для вашего сценария вы должны создать класс 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 прямо указано, что в этом случае должен работать «синтаксис выражения». Может быть, это ошибка?

Homr Zodyssey 23.07.2021 15:55

Другие вопросы по теме