【发布时间】:2016-11-29 16:43:38
【问题描述】:
我正在从事一个数据迁移项目 - API 到 API。
目标 API 是 graphQL,我们有许多对象要推送到目标中,并且形状各不相同,所以我正在寻找一些关于如何最好地在 c# 中动态构建突变/查询的建议。
目前我们只是使用模板并使用查找/替换例程来注入值。虽然随着数据形状的变化,这种方法确实有效,但它变得越来越复杂和不优雅。
我正在寻找任何可能遇到过类似情况或知道我应该查看的任何库的人的任何建议/指针。
【问题讨论】:
我正在从事一个数据迁移项目 - API 到 API。
目标 API 是 graphQL,我们有许多对象要推送到目标中,并且形状各不相同,所以我正在寻找一些关于如何最好地在 c# 中动态构建突变/查询的建议。
目前我们只是使用模板并使用查找/替换例程来注入值。虽然随着数据形状的变化,这种方法确实有效,但它变得越来越复杂和不优雅。
我正在寻找任何可能遇到过类似情况或知道我应该查看的任何库的人的任何建议/指针。
【问题讨论】:
更新 - 13/02/2018
我已经更新了这个怪物以迎合嵌套子选择和 GraphQl 枚举,所以如果有人对这里感兴趣,可以在 GitHub
原答案
我也有同样的要求。在那里找不到任何东西,所以我想出了这个非常不雅的解决方案。它适用于我的场景,因此我将在此处发布给其他寻求解决方案的人。
public static class GraphQlObjectParser
{
public static string Parse(string queryType, string queryName, string[] subSelection, object @object = null, string objectTypeName = null)
{
var query = queryType + "{" + queryName;
if (@object != null)
{
query += "(";
if (objectTypeName != null)
{
query += objectTypeName + ":" + "{";
}
var queryData = string.Empty;
foreach (var propertyInfo in @object.GetType().GetProperties())
{
var value = propertyInfo.GetValue(@object);
if (value != null)
{
var type = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;
var valueQuotes = type == typeof(string) ? "\"" : string.Empty;
var queryPart = char.ToLowerInvariant(propertyInfo.Name[0]) + propertyInfo.Name.Substring(1) + ":" + valueQuotes + value + valueQuotes;
queryData += queryData.Length > 0 ? "," + queryPart : queryPart;
}
}
query += (objectTypeName != null ? queryData + "}" : queryData) + ")";
}
if (subSelection.Length > 0)
{
query += subSelection.Aggregate("{", (current, s) => current + (current.Length > 1 ? "," + s : s)) + "}";
}
query += "}";
return query;
}
}
这适用于查询和突变。用法示例如下:
var query = GraphQlObjectParser.Parse("query", "users", new[] { "id", "name" });
会给你
query{users{id,name}}
或
var query = GraphQlObjectParser.Parse("query", "user", new[] { "id", "name" }, new User { Id = 1 });
会给你
query{user(id:1){id,name}}
或
var query = GraphQlObjectParser.Parse("mutation", "user", new[] { "id", "name" }, new User { Id = 1, Name = "John" }, "data");
会给你
mutation{user(data:{id:1,name:"John"}){id,name}}
它将与枚举一起使用,这就是为什么我首先需要这个解决方案。您可以传入不带对象的子选择或不带对象类型名称的对象。尽管我还没有满足子选择的子选择,但我已经尝试覆盖尽可能多的基础。如果/当我编写这个代码时,我会在这里更新。
希望对某人有所帮助。
【讨论】: