LINQ查询输出JSON中的组和子组

时间:2012-09-26 13:32:13

标签: c# asp.net json linq entity-framework

我有一个这样的表(群组):

ID       Name           ParentID
1        Group 1        null
2        Group 2        null
3        SubGr 1-1      1
4        SubGr 1-2      1
5        SubGr 2-1      2
6        Group 3        null
7        SubGr 1-2-1    4
..... and so on

我想将此序列化为JSON,如下所示:

[{"id":1,
  "name":"Group 1",
  "children": [
    {
     "id":3,
     "name":"SubGr 1-1",
     "children":null
    },{
     "id":4,
     "name":"SubGr 1-2",
     "children": [
       {
        "id":7,
        "name":"SubGr 1-2-1", 
        "children": null
       }
      ]
    }
   ]
  },
 {"id":2,
  "name":"Group 2",
  "children": [
    {
     "id":5,
     "name":"SubGr 2-1",
     "children":null
    }
   ]
 },
 {"id":6,
  "name": "Group 3",
  "children": null
 }
]

如您所见,您可以拥有不确定的子组。

如何在LINQ中进行此类查询并以JSON方式输出,如上例所示?

使用ParentID输出JSON作为分隔元素没有问题,但我需要具有上述结构。

这是我目前正在使用的代码,在尝试了不同的东西之后,但仍然没有运气(此版本仅提供两个级别):

    public ActionResult GetGroups()
    {
        var groupobjs = db.GroupObjs.ToList();

        var items = groupobjs.Where(p => p.ParentID == null).Select(p => new
        {
            id = p.ID,
            name = p.Name,
            children = groupobjs.Where(c => c.ParentID == p.ID).Select(c => new {
                id = c.ID,
                name = c.Name
            })
        });



        return Json(items, JsonRequestBehavior.AllowGet);
    }      

2 个答案:

答案 0 :(得分:2)

我正在研究一些类似于@ Hunter-974推荐的代码。

public class Group
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int? ParentId { get; set; }
    public List<Group> Subgroups { get; set; }

    public Group()
    {
        this.Subgroups = new List<Group>();
    }
}

class Program
{
    static void Main()
    {
        Group[] groups = new Group[]
        {
            new Group { Id = 1, Name = "Group 1", ParentId = null },
            new Group { Id = 2, Name = "Group 2", ParentId = null },
            new Group { Id = 3, Name = "SubGr 1-1", ParentId = 1 },
            new Group { Id = 4, Name = "SubGr 1-2", ParentId = 1 },
            new Group { Id = 5, Name = "SubGr 2-1", ParentId = 2 },
            new Group { Id = 6, Name = "Group 3", ParentId = null },
            new Group { Id = 7, Name = "SubGr 1-2-1", ParentId = 4 }
        };

        foreach (Group g in groups)
            if (g.ParentId.HasValue)
                groups.Single(group => group.Id == g.ParentId.Value).Subgroups.Add(g);

        var rootgroups = groups.Where(g => g.ParentId == null);

        JavaScriptSerializer js = new JavaScriptSerializer();
        Console.WriteLine(js.Serialize(rootgroups));
    }
}

答案 1 :(得分:0)

我认为您应该使用递归方法而不是LINQ来执行此操作。

1)定义一个表示组的类,具有属性ID(int),属性Name(字符串),属性Children(List),属性Parent(int ?, not serialized)和方法Serialize( )(谁为每个儿童组调用序列化)

2)定义一个包含“root”组的List,以及一个包含所有组的List。

3)对于数据表的每一行,创建一个对象组。定义其所有属性。显然,孩子的名单将是空的。

4)对于每个组,如果父级的ID不为空,则将其添加到其父级。这样,您将填写所有组的“儿童”列表。

5)对于每个组,如果父母的ID为空,请将该组添加到“根”列表中。

6)对于Roots列表中的每个Group,调用Serialize。方法。

我希望这会对你有所帮助。问我是否需要更多解释或代码而不是它们。