将分层数据表转换为Json [英] Convert Hierarchical DataTable to Json

查看:195
本文介绍了将分层数据表转换为Json的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个分层数据表如下,生成菜单及其子菜单。主菜单的parentId为0.子菜单中有父Id代表parentId。



  ResourceId DisplayName ParentId Url ---------- ------------------------------------- 1首页0一些Url2学生0一些Url3员工0一些Url4图书馆0 Some Url6 StudentAtt 1 Some Url7 TimeTable 1 Some Url8 Staff Att 2 Some Url9 Book Issue 3 Some Url10 Book Returns 3 Some Url11费用付款4 Some Url12 Book fine 10 Some Url  



需要将其转换为Json。以下是我试过的代码。我试图检查SubMenu的ParentId是否等于Main Menu的ResourceId。但是不显示子菜单。 (变量表是DataTable)



  var rows = table.Rows.Cast< DataRow>()ToList(); var result = rows.Where(x => x [ParentId] ToString()==0)GroupBy(r => new {x = r [ResourceId]})。 => new {// MenuLevel = g.Key.x,MenuDetails = g.GroupBy(r => new {a = r [DisplayName],b = r [Url]})。 => new {DisplayName = detail.Key.a,Url = detail.Key.b,SubMenu = detail.Where(y => g.Key.x.ToString()== y [ParentId]。ToString ())GroupBy(r => new {f = r [DisplayName]})选择(subMenu => new {SubMenuDisplayName = subMenu.Key.f})})});  



我得到的结果如下:

  [{MenuDetails:[{DisplayName:Home,Url:null,SubMenu:[]}]},{ MenuDetails:[{DisplayName:Student,Url:null,SubMenu:[]}]},{MenuDetails SubMenu:[]}]},{MenuDetails:[{DisplayName:Library,Url:null,SubMenu:[]}]}] 

但预期的结果是:

  {MenuDetails:[{DisplayName:Home,Url:null,SubMenu:[{SubMenuDisplayName:StudentAtt},{SubMenuDisplayName:TimeTable}]}]}, {MenuDetails:[{DisplayName:Student,Url:null,SubMenu:[{SubMenuDisplayName:Staff Att}]}]},{MenuDetails:[{DisplayName :Staff,Url:null,SubMenu:[{SubMenuDisplayName:Book Issue},{SubMenuDisplayName:Book Return}]}]},{MenuDetails DisplayName:Library,Url:null,SubMenu:[{SubMenuDisplayName:Fee Payment}]}]}] 

我还需要显示子子菜单(其父ID指向子菜单的资源ID)任何一个请帮助

解决方案

您所在的问题

  SubMenu = detail.Where(y => ... 

,细节已被过滤到 rows.Where(x = > x [ParentId] ToString()==0)所以它不包括子项。



将更接近你想要的,但只返回前两个级别。

  var result = rows.Where(x => x [ParentId] ToString()==0)。GroupBy(r => new {x = r [ResourceId]})选择(
g => new {
// MenuLevel = g.Key.x,
MenuDetails = g.GroupBy(r => new {a = r [DisplayName],b = r [Url]})。 b $ b detail => new {
DisplayName = detail.Key.a,
Url = detail.Key.b,
SubMenu =
rows.Where(y => ; g.Key.x.ToString()== y [ParentId]。ToString())。
GroupBy(r => new {f = r [DisplayName]})。 b $ b subMenu => new {
SubMenuDisplay Name = subMenu.Key.f
}

}

});

要创建完整的层次结构,您需要为每个菜单项创建对象,然后将它们连接在一起。如果您创建一个表示菜单项的类型,这将更容易,例如:

  public class MenuDeatils {

public int ID;
public string Url;
public string DisplayName;
public IEnumerable< MenuDeatils>子菜单

}

然后,您可以为每个项目创建一个对象并对其进行分组通过他们的ParentIds:

  var groups =(从行中的行
组逐行[ParentId] into parentGroup
选择新的{
Key =(int)parentGroup.Key,
Items = parentGroup.Select(r => new MenuDeatils {
ID =(int)r [ ResourceId],
DisplayName =(string)r [DisplayName],
Url =(string)r [Url]
})
})ToList );

注意:这里查询的列举(.ToList()),所以我们创建一组MenuDeatils对象



接下来,我们可以从我们创建的组中设置每个MenuDetails对象的SubMenu属性。

  foreach(var menuItem in groups.SelectMany(g => g.Items)){
var submenu = groups.SingleOrDefault(g => g.Key == menuItem.ID);
if(submenu!= null){
menuItem.SubMenu = submenu.Items;
}
};

顶级项目可以通过以下方式找到:

  var result = groups.Single(g => g.Key == 0).Items 

,现在附有所有后代菜单。


I have a hierarchial data table as follows which generates menu and its sub menus. main menu has parentId as 0. Submenu has parent Ids referring to parentId.

ResourceId   DisplayName   ParentId     Url
-----------------------------------------------
1           Home           0            Some Url
2           Student        0            Some Url
3           Staff          0            Some Url
4           Library        0            Some Url
6           StudentAtt     1            Some Url
7           TimeTable      1            Some Url
8           Staff Att      2            Some Url
9           Book Issue     3            Some Url
10          Book Return    3            Some Url
11          Fee Payment    4            Some Url
12          Book fine      10           Some Url

need to convert it to Json. Below is the code i tried out. I am trying to check if ParentId of SubMenu equals ResourceId of main Menu. But subMenu is not displayed. (variable table is DataTable)

var rows = table.Rows.Cast<DataRow>().ToList();
            var result = rows.Where(x => x["ParentId"].ToString() == "0").GroupBy(r => new { x = r["ResourceId"] }).Select(
                g => new
                {
                    //MenuLevel = g.Key.x,
                    MenuDetails = g.GroupBy(r => new {a = r["DisplayName"], b = r["Url"]}).Select(
                        detail => new
                        {
                            DisplayName = detail.Key.a,
                            Url = detail.Key.b,
                            SubMenu =
                                detail.Where(y => g.Key.x.ToString()==y["ParentId"].ToString()).
                                    GroupBy(r => new {f = r["DisplayName"]}).Select(
                                    subMenu=>new
                                    {
                                        SubMenuDisplayName=subMenu.Key.f
                                    }
                                    )
                        }
                        )
                });

the result i got is as below.

[{"MenuDetails":[{"DisplayName":"Home","Url":null,"SubMenu":[]}]},{"MenuDetails":[{"DisplayName":"Student","Url":null,"SubMenu":[]}]},{"MenuDetails":[{"DisplayName":"Staff","Url":null,"SubMenu":[]}]},{"MenuDetails":[{"DisplayName":"Library","Url":null,"SubMenu":[]}]}]

But expected result is:

[{"MenuDetails":[{"DisplayName":"Home","Url":null,"SubMenu":[{"SubMenuDisplayName":"StudentAtt"},{"SubMenuDisplayName":"TimeTable"}]}]},{"MenuDetails":[{"DisplayName":"Student","Url":null,"SubMenu":[{"SubMenuDisplayName":"Staff Att"}]}]},{"MenuDetails":[{"DisplayName":"Staff","Url":null,"SubMenu":[{"SubMenuDisplayName":"Book Issue"},{"SubMenuDisplayName":"Book Return"}]}]},{"MenuDetails":[{"DisplayName":"Library","Url":null,"SubMenu":[{"SubMenuDisplayName":"Fee Payment "}]}]}]

I also need to display the sub sub menu (which has parent id pointing to resource id of sub menu) Any one please help

解决方案

The issue your having is in

SubMenu = detail.Where(y => ...

, detail is already filtered to rows.Where(x => x["ParentId"].ToString() == "0") so it does not include the child items.

This would be closer to what you want but only returns the first two levels.

var result = rows.Where(x => x["ParentId"].ToString() == "0").GroupBy(r => new { x = r["ResourceId"] }).Select(
    g => new {
        //MenuLevel = g.Key.x,
        MenuDetails = g.GroupBy(r => new { a = r["DisplayName"], b = r["Url"] }).Select(
            detail => new {
                DisplayName = detail.Key.a,
                Url = detail.Key.b,
                SubMenu =
                    rows.Where(y => g.Key.x.ToString() == y["ParentId"].ToString()).
                        GroupBy(r => new { f = r["DisplayName"] }).Select(
                        subMenu => new {
                            SubMenuDisplayName = subMenu.Key.f
                        }
                        )
            }
            )
    });

To create the full hierarchy you need to create objects for each menu item then join them together. This is easier if you create a type to represent your menu item, for example:

public class MenuDeatils {

    public int ID;
    public string Url;
    public string DisplayName;
    public IEnumerable<MenuDeatils> SubMenu;

}

You can then create an object for each item and group them by their ParentIds:

var groups = (from row in rows
              group row by row["ParentId"] into parentGroup
              select new {
                Key = (int)parentGroup.Key,
                Items = parentGroup.Select(r => new MenuDeatils {
                    ID = (int)r["ResourceId"],
                    DisplayName = (string)r["DisplayName"],
                    Url = (string)r["Url"]
                })
              }).ToList();

Note: The queries are enumerated here (.ToList()) so we create one set of MenuDeatils objects.

Next we can set each MenuDetails object's SubMenu property from the groups we have created.

foreach (var menuItem in groups.SelectMany(g => g.Items)) {
    var submenu = groups.SingleOrDefault(g => g.Key == menuItem.ID);
    if (submenu != null) {
        menuItem.SubMenu = submenu.Items;
    }
};

The top level items can be found with:

var result = groups.Single(g => g.Key == 0).Items

, and now have all the descendant menus attached.

这篇关于将分层数据表转换为Json的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆