我有一个简单的枚举,试图将其包含在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);
}
}
)
答案 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>
继承,然后再执行与上述相同的自定义解析器。
答案 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
。