【问题标题】:Build JSON Hierarchy from Structured Data从结构化数据构建 JSON 层次结构
【发布时间】:2013-10-08 19:27:51
【问题描述】:

C# | .NET 4.5 |实体框架 5

我有从 SQL 查询返回的 ID、ParentID、Name 形式的数据。我想获取该数据并将其解析为分层 JSON 字符串。到目前为止,这似乎是一项比应有的艰巨任务。由于我使用的是实体,因此数据作为 IEnumerable 很好地返回给我。现在我相信我只需要某种形式的递归,但我不太确定从哪里开始。任何帮助表示赞赏。

数据返回为

id parentId 名称 1 1 顶部位置 2 1 位置 1 3 1 位置 2 4 2 位置1A

代码是

public static string GetJsonLocationHierarchy(long locationID)
{
    using (EntitiesSettings context = new EntitiesSettings())
    {
        // IEnumerable of ID,ParentID,Name
        context.GetLocationHierarchy(locationID);
    }
}

我希望的最终结果是这样的:

{
    "id": "1",
    "parentId": "1",
    "name": "TopLoc",
    "children": [
        {
            "id": "2",
            "parentId": "1",
            "name": "Loc1",
            "children": [
                {
                    "id": "4",
                    "parentId": "2",
                    "name": "Loc1A",
                    "children": [
                        {}
                    ]
                }
            ]
        },
        {
            "id": "3",
            "parentId": "1",
            "name": "Loc2",
            "children": [
                {}
            ]
        }
    ]
}

【问题讨论】:

    标签: c# json entity-framework json.net hierarchy


    【解决方案1】:

    将平面表转换为层次结构的一种方法是将所有节点放入字典中。然后遍历字典,并为每个节点查找其父节点并将其添加到父节点的子节点。从那里,您只需要找到根并对其进行序列化。

    这是一个演示该方法的示例程序:

    class Program
    {
        static void Main(string[] args)
        {
            IEnumerable<Location> locations = new List<Location>
            {
                new Location { Id = 1, ParentId = 1, Name = "TopLoc" },
                new Location { Id = 2, ParentId = 1, Name = "Loc1" },
                new Location { Id = 3, ParentId = 1, Name = "Loc2" },
                new Location { Id = 4, ParentId = 2, Name = "Loc1A" },
            };
    
            Dictionary<int, Location> dict = locations.ToDictionary(loc => loc.Id);
    
            foreach (Location loc in dict.Values)
            {
                if (loc.ParentId != loc.Id)
                {
                    Location parent = dict[loc.ParentId];
                    parent.Children.Add(loc);
                }
            }
    
            Location root = dict.Values.First(loc => loc.ParentId == loc.Id);
    
            JsonSerializerSettings settings = new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver(),
                Formatting = Formatting.Indented
            };
            string json = JsonConvert.SerializeObject(root, settings);
    
            Console.WriteLine(json);
        }
    }
    
    class Location
    {
        public Location()
        {
            Children = new List<Location>();
        }
    
        public int Id { get; set; }
        public int ParentId { get; set; }
        public string Name { get; set; }
        public List<Location> Children { get; set; }
    }
    

    这是输出:

    {
      "id": 1,
      "parentId": 1,
      "name": "TopLoc",
      "children": [
        {
          "id": 2,
          "parentId": 1,
          "name": "Loc1",
          "children": [
            {
              "id": 4,
              "parentId": 2,
              "name": "Loc1A",
              "children": []
            }
          ]
        },
        {
          "id": 3,
          "parentId": 1,
          "name": "Loc2",
          "children": []
        }
      ]
    }
    

    【讨论】:

    • 反序列化的最佳方法是什么?
    • @Rod 要反序列化你只需要Location loc = JsonConvert.DeserializeObject&lt;Location&gt;(json);
    • 非常感谢:)
    • 您对如何采用层次结构(json 或 poco)并将其展平到数据库有任何想法吗?我试图弄清楚如何获取一个新的分层对象并将(作为新记录)插入到数据库中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-08
    • 2015-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多