9

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": [
                {}
            ]
        }
    ]
}
4

1 回答 1

12

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

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

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": []
    }
  ]
}
于 2013-10-08T21:43:32.863 回答