我正在编写.NET服务,以使用(获取)来自包含数据的Web服务的JSON数组,如果在数据库中,则将其标准化为单独的相关表。 JSON数组将随每个元素重复父数据属性而出现,只有子元素的属性会在元素之间变化。所以这是JSON对象的样子:
[ {
"parentID": 123,
"parentName": "Parent Name",
"childID": 1,
"childName": "First Child",
"subChildID": null,
"subChildName": null
},
{
"parentID": 123,
"parentName": "Parent Name",
"childID": 2,
"childName": "Second Child",
"subChildID": null,
"subChildName": null
},
{
"parentID": 123,
"parentName": "Parent Name",
"childID": 3,
"childName": "Third Child",
"subChildID": 100,
"subChildName": "First Subchild of the third child"
},
{
"parentID": 123,
"parentName": "Parent Name",
"childID": 4,
"childName": "Third child",
"subChildID": 101,
"subChildName": "Second subchild of the third child"
}]
但是我需要将此数组(希望是使用Newtonsoft或Linq库吗?)转换成一个.NET对象,它看起来像这样:
public class ParentObject
{
public int parentID { get; set; }
public string parentName { get; set; }
public List<ChildObject> children { get; set; }
private class ChildObject
{
public int childID { get; set; }
public string childName { get; set; }
public List<SubChildObject> subChildren { get; set; }
private class SubChildObject
{
public int subChildID { get; set; }
public string subChildName { get; set; }
}
}
}
我看到了相反的例子;将嵌套对象展平为类似列表的对象,但不是我要的对象。同样,我希望可以通过Newtonsoft或纯Linq的Json库来实现。谢谢。
答案 0 :(得分:1)
我确定可以使用Linq完成此 ,但是只需循环即可轻松实现,如以下示例代码所示:
List<ParentObject> CreateEntities(string json)
{
var entities = JsonConvert.DeserializeObject<List<RootObject>>(json);
List<ParentObject> parents = new List<ParentObject>();
foreach (var entity in entities)
{
if (parents.Any(p => p.parentID == entity.parentID))
{
var parent = parents.Single(p => p.parentID == entity.parentID);
if (parent.children.Any(c => c.childID == entity.childID))
{
var child = parent.children.Single(c => c.childID == entity.childID);
if (entity.subChildID.HasValue)
{
child.subChildren.Add(new ParentObject.ChildObject.SubChildObject
{
subChildID = entity.subChildID.Value,
subChildName = entity.subChildName
});
}
}
else
{
var newChild = (new ParentObject.ChildObject
{
childID = entity.childID,
childName = entity.childName,
subChildren = new List<ParentObject.ChildObject.SubChildObject>()
});
if (entity.subChildID.HasValue)
{
newChild.subChildren.Add(new ParentObject.ChildObject.SubChildObject
{
subChildID = entity.subChildID.Value,
subChildName = entity.subChildName
});
}
parent.children.Add(newChild);
}
}
else
{
var newParent = new ParentObject
{
parentID = entity.parentID,
parentName = entity.parentName,
children = new List<ParentObject.ChildObject>
{
new ParentObject.ChildObject
{
childID = entity.childID,
childName = entity.childName,
subChildren = new List<ParentObject.ChildObject.SubChildObject>()
}
}
};
if (entity.subChildID.HasValue)
{
newParent.children.Single().subChildren.Add(new ParentObject.ChildObject.SubChildObject
{
subChildID = entity.subChildID.Value,
subChildName = entity.subChildName
});
}
parents.Add(newParent);
}
}
return parents;
}
public class RootObject
{
public int parentID { get; set; }
public string parentName { get; set; }
public int childID { get; set; }
public string childName { get; set; }
public int? subChildID { get; set; }
public string subChildName { get; set; }
}
public class ParentObject
{
public int parentID { get; set; }
public string parentName { get; set; }
public List<ChildObject> children { get; set; }
public class ChildObject
{
public int childID { get; set; }
public string childName { get; set; }
public List<SubChildObject> subChildren { get; set; }
public class SubChildObject
{
public int subChildID { get; set; }
public string subChildName { get; set; }
}
}
}
输出:
注意:
此代码可在一个响应中处理多个父母,就像您的问题表明我不确定每个响应只有一个父母一样。
答案 1 :(得分:1)
JSON中的“第三个孩子”对象都具有不同的名称“第三个孩子”和“第三个 C hild”以及不同的ID 3和4,我将这些字段设置为相同,以获得更好的输出结果。
我还使用int?
作为ID,因为JSON具有可空的int字段和Tuples(C#7.0)而不是匿名对象。
您可以删除Where
过滤器来收集ID为空的对象。
如果您有任何疑问或需要修复,请告诉我,这是代码:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp1
{
internal class Program
{
private static void Main(string[] args)
{
string json = @"[
{
""parentID"": 123,
""parentName"": ""Parent Name"",
""childID"": 1,
""childName"": ""First Child"",
""subChildID"": null,
""subChildName"": null
},
{
""parentID"": 123,
""parentName"": ""Parent Name"",
""childID"": 2,
""childName"": ""Second Child"",
""subChildID"": null,
""subChildName"": null
},
{
""parentID"": 123,
""parentName"": ""Parent Name"",
""childID"": 3,
""childName"": ""Third child"",
""subChildID"": 100,
""subChildName"": ""First Subchild of the third child""
},
{
""parentID"": 123,
""parentName"": ""Parent Name"",
""childID"": 3,
""childName"": ""Third child"",
""subChildID"": 101,
""subChildName"": ""Second subchild of the third child""
}
]";
JArray jarr = JArray.Parse(json);
IEnumerable<ParentObject> parents = jarr.GroupBy(t => ((int?)t["parentID"], (string)t["parentName"]))
.Select(pg => new ParentObject
{
parentID = pg.Key.Item1,
parentName = pg.Key.Item2,
children = pg
.GroupBy(t => ((int?)t["childID"], (string)t["childName"]))
.Select(cg => new ParentObject.ChildObject()
{
childID = cg.Key.Item1,
childName = cg.Key.Item2,
subChildren = cg
.Select(t => new ParentObject.ChildObject.SubChildObject()
{
subChildID = (int?)t["subChildID"],
subChildName = (string)t["subChildName"]
}).Where(s => s.subChildID != null).ToList()
}).Where(c => c.childID != null).ToList()
}).Where(p => p.parentID != null).ToList();
json = JsonConvert.SerializeObject(parents, Formatting.Indented);
Console.WriteLine(json);
Console.ReadKey();
}
}
public class ParentObject
{
public int? parentID { get; set; }
public string parentName { get; set; }
public List<ChildObject> children { get; set; }
public class ChildObject
{
public int? childID { get; set; }
public string childName { get; set; }
public List<SubChildObject> subChildren { get; set; }
public class SubChildObject
{
public int? subChildID { get; set; }
public string subChildName { get; set; }
}
}
}
}