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
发布评论