【发布时间】:2019-11-18 15:30:39
【问题描述】:
以下 javascript 问题与我尝试解决的问题相同,但在 c# 中
How can I merge 2 dot notation strings to a GraphQL query string
预期的结构是
{
"Case": {
"Owner": {
"Name": null,
"ProfilePic": null
},
"CaseNo": null,
"FieldOfLaw":{
"Name": null
},
"CaseType": {
"Name": null
},
"CaseSubType": {
"Name": null
},
},
"Client":{
"Policy":{
"PolicyNo": null
}
}
}
我目前的输出是
{
"Case": {
"Owner": {
"Name": null,
"ProfilePic": null
},
"CaseNo": null,
"FieldOfLaw": null,
"CaseType": null,
"CaseSubType": null
}
}
下面是我尝试使用 ExpandoObjects 来尝试动态生成所需的对象。任何正确方向的建议或指示将不胜感激。
public static void Main(string[] args)
{
var FieldList = new List<string>
{
"Case.Owner.Name",
"Case.Owner.ProfilePic",
"Case.CaseNo",
"Case.FieldOfLaw.Name",
"Case.CaseType.Name",
"Case.CaseSubType.Name",
"Client.Policy.PolicyNo",
};
Parser graphQL = new Parser();
var result = graphQL.Parse(FieldList);
Console.Write(result);
}
下面是实际的 parse 方法,所以我在每个元素上运行一个聚合函数来创建并返回 expando 对象到初始持有者。我递归遍历每个拆分字符串,一旦拆分列表中没有剩余项目,我就退出递归。
public class Parser
{
public string Parse(List<string> fieldList)
{
// List<ExpandoObject> queryHolder = new List<ExpandoObject>();
ExpandoObject intialSeed = new ExpandoObject();
fieldList.Aggregate(intialSeed, (holder, field) =>
{
holder = ParseToObject(holder, field.Split('.').ToList());
return holder;
});
return JsonConvert.SerializeObject(intialSeed);
}
public ExpandoObject ParseToObject(ExpandoObject holder, List<string> fieldSplit, string previousKey = null)
{
if (fieldSplit.Any())
{
var item = fieldSplit.Shift();
if (item == null)
return holder;
// If the current item doesn't exists in the dictionary
if (!((IDictionary<string, object>)holder).ContainsKey(item))
{
if (((IDictionary<string, object>)holder).Keys.Count() == 0)
holder.TryAdd(item, null);
else
_ = ((IDictionary<string, object>)holder).GetItemByKeyRecursively(previousKey, item);
}
previousKey = item;
ParseToObject(holder, fieldSplit, previousKey);
}
return holder;
}
}
这是我的两个扩展方法,当 GetItemByKeyRecursively 在它的递归中进入第三级时,我遇到了问题,例如。
我正在添加 FieldOfLaw,它将属性添加到 Case expandoObject 但不知道如何返回包含 Owner、CaseNo 等的叶子。
public static class CollectionExtensions
{
public static T Shift<T>(this IList<T> list)
{
var shiftedElement = list.FirstOrDefault();
list.RemoveAt(0);
return shiftedElement;
}
public static IDictionary<string, object> GetItemByKeyRecursively(this IDictionary<string, object> dictionary, string parentKey, string keyToCreate)
{
foreach (string key in dictionary.Keys)
{
var leaf = dictionary[key];
if (key == parentKey)
{
var @value = dictionary[key];
if (@value is ExpandoObject)
{
(@value as ExpandoObject).TryAdd(keyToCreate, null);
}
else if (@value == null)
{
var item = new ExpandoObject();
item.TryAdd(keyToCreate, null);
dictionary[key] = item;
}
return dictionary;
}
if (leaf == null)
continue;
return GetItemByKeyRecursively((IDictionary<string, object>)leaf, parentKey, keyToCreate);
}
return null;
}
}
【问题讨论】: