2015-02-13 4 views
2

У меня есть таблица иерархических данных следующим образом, которая генерирует меню и его подменю. Главное меню имеет parentId как 0. Подменю имеет родительские идентификаторы, относящиеся к parentId.Преобразование иерархических данных в Json

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

необходимо преобразовать его в Json. Ниже приведен код, который я пробовал. Я пытаюсь проверить, соответствует ли ParentId из SubMenu ResourceId главного меню. Но subMenu не отображается. (Переменная таблица 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 
 
            } 
 
            ) 
 
         } 
 
         ) 
 
       });

результат я получил, как показано ниже.

[{"MenuDetails":[{"DisplayName":"Home","Url":null,"SubMenu":[]}]},{"MenuDetails":[{"DisplayName":"Student","Url":null,"SubMenu":[]}]},{"MenuDetails":[{"DisplayName":"Staff","Url":null,"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 "}]}]}] 

Мне также нужно, чтобы отобразить меню суб суб (который родительский идентификатор, указывающий на идентификатор ресурса субменю) Любой, пожалуйста, помогите

ответ

0

эммитирование имея это в

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"] }).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 
         } 
         ) 
      } 
      ) 
    }); 

Чтобы создать полную иерархию, вам необходимо создать объекты для каждого элемента меню, а затем объединить их. Это проще, если вы создаете тип для представления вашего пункта меню, например:

public class MenuDeatils { 

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

} 

Вы можете создать объект для каждого элемента и группировать их по их 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(); 

Примечание: Здесь перечислены запросы (.ToList()), поэтому мы создаем один набор объектов MenuDeatils.

Далее мы можем установить каждое свойство SubMenu объекта MenuDetails из созданных нами групп.

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 

, и теперь все прикрепленные меню потомка.

Смежные вопросы