我正在从事一个数据迁移项目 - 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;
}
}
Run Code Online (Sandbox Code Playgroud)
这适用于查询和突变。用法示例有:
var query = GraphQlObjectParser.Parse("query", "users", new[] { "id", "name" });
Run Code Online (Sandbox Code Playgroud)
会给你
query{users{id,name}}
Run Code Online (Sandbox Code Playgroud)
或者
var query = GraphQlObjectParser.Parse("query", "user", new[] { "id", "name" }, new User { Id = 1 });
Run Code Online (Sandbox Code Playgroud)
会给你
query{user(id:1){id,name}}
Run Code Online (Sandbox Code Playgroud)
或者
var query = GraphQlObjectParser.Parse("mutation", "user", new[] { "id", "name" }, new User { Id = 1, Name = "John" }, "data");
Run Code Online (Sandbox Code Playgroud)
会给你
mutation{user(data:{id:1,name:"John"}){id,name}}
Run Code Online (Sandbox Code Playgroud)
它将与枚举一起使用,这就是我首先需要这个解决方案的原因。您可以传入不带对象的子选择或不带对象类型名称的对象。尽管我还没有满足子选择的子选择的需求,但我已尝试涵盖尽可能多的基础。如果/当我编写这个代码时,我会在这里更新。
希望它能帮助某人。