2

私はこのようなテーブルを持っています(グループ):

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 を個別の要素として出力しても問題ありませんが、上記のような構造にする必要があります。

これは、さまざまなことを試した後、現在取り組んでいるコードですが、まだ運がありません (このバージョンでは 2 つのレベルしか提供されません)。

    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);
    }      
4

2 に答える 2

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));
    }
}
于 2012-09-26T14:50:04.387 に答える
0

これを行うには、LINQの代わりに再帰メソッドを使用する必要があると思います。

1)プロパティID(int)、プロパティName(string)、プロパティChildren(List)、プロパティParent(int ?、シリアル化されていない)、およびメソッドSerialize()(who子供のグループごとにSerializeを呼び出します)

2)「ルート」グループを含むリストと、すべてのグループを含むリストを定義します。

3)データテーブルの各行に対して、オブジェクトグループを作成します。そのすべてのプロパティを定義します。明らかに、子のリストは空になります。

4)各グループについて、親のIDがnullでない場合は、それを親に追加します。このようにして、すべてのグループの子リストに入力します。

5)グループごとに、親のIDがnullの場合は、グループをルートリストに追加します。

6)Rootsリストのグループごとに、Serializeメソッドを呼び出します。

これがお役に立てば幸いです。それらの代わりにもっと説明やコードが必要かどうか私に尋ねてください。

于 2012-09-26T13:54:40.743 に答える