GraphQL.NET如何将枚举添加到GraphQL类型

时间:2019-03-01 19:09:30

标签: asp.net .net asp.net-core .net-core graphql

我有一个简单的枚举,试图将其包含在GraphQL类型中,并收到以下错误消息:

  

父类型“ NewsItemType”上字段“ Category”的GraphQL类型   不能隐式导出。

     

------------------不能隐式派生父类型“ NewsItemType”上字段“ Category”的GraphQL类型。

     

---------------类型:NewsType无法有效地强制为GraphQL类型参数名称: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);
                }
            }
        )

2 个答案:

答案 0 :(得分:1)

这是为您的案例快速执行此操作的方法。基本上,您不使用默认的lambda表达式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

答案 1 :(得分:1)

我也很难使它也能正常工作。在这方面显然缺少官方文档。我使用它的方式是基于我在this article中找到的东西。

对于您的方案,您将为枚举创建一个“ 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