2011-01-14 19 views
8

Mam najtrudniejszy czas na przekształcenie listy (folderu) w hierarchię.Lista z listą do hierarchii

Public Class Folder 

Public Property FolderID() As Integer 
Public Property Name() As String 
Public Property ParentFolderID() As Integer 
Public Property Children() as IEnumerable(Of Folder) 

End Class 

Muszę zwrócić listę (z folderu) z dziećmi.

Buduję listę (folderu) z danych w bazie danych.

{1, "Folder 1" nic} {2 "katalog 2", 1} {3 "Folder 3", 2} {4 "Folder 4", 3} {5 , "Folder 5", Nic}

Nie mogę określić, jak rekursywnie przenieść foldery podrzędne do właściwości Dzieci ich rodzica.

Chciałbym to zrobić z LINQ.

Każda pomoc jest bardzo doceniana.

Aktualizacja

Dziękuję za odpowiedź, ale nie całkiem tam. W oparciu o twoją odpowiedź wymyśliłem to, co prawie działa.

Dim list = (From folder in folderList Select New Folder() With { 
    .FolderID = folder.FolderID, 
    .Name = folder.Name, 
    .ParentFolderID = folder.ParentFolderID, 
    .Children = (From child in folderList 
       Where child.ParentFolderID = item.FolderID).ToList()}).ToList() 

{1, "Root", Nothing} 
{2, "Child", 1} 
{3, "Grand Child", 2} 

uzyskać listę wszystkich trzech folderów:

Root 
--Child 
Child 
--Grand Child 
Grand Child 

powinna wyglądać następująco:

Root 
--Child 
----Grand Child 

Odpowiedz

0

C# wersja

var newList = list.Select(o=> 
    new Fodler 
    { 
     FodlerID = o.FodlerID, 
     Children = list.Where(q => q.ParentId == o.FodlerID), 
     Parent = list.FirstOrDefault(q => q.FodlerID == o.ParentID), 
     //Other properties goes here 
    }); 

Chociaż jeśli nie poprawne mapowanie na przykład EF, powinno to być zrobione automatycznie.

12

To proste, jeśli używasz metody rozszerzenia ToLookup.

C#:

var lookup = folderList.ToLookup(f => f.ParentFolderID); 

foreach (var folder in folderList) 
{ 
    folder.Children = lookup[folder.FolderID].ToList(); 
} 

var rootFolders = lookup[null].ToList(); 

VB:

Dim lookup = folderList.ToLookup(Function (f) f.ParentFolderID) 

For Each folder In folderList 
    folder.Children = lookup(folder.FolderID).ToList() 
Next 

Dim rootFolders = lookup(Nothing).ToList() 
+0

Przyjemne użycie rozszerzenia ToLookup. –

0

Spróbuj metodę rozszerzenia:

public static IEnumerable<T> AsHierarchy<T>(this IEnumerable<T> collection, 
     Func<T, T> parentSelector, Expression<Func<T, IEnumerable<T>>> childrenSelector, T root = default(T)) 
    { 
     var items = collection.Where(x => parentSelector(x).Equals(root)); 
     foreach (var item in items) 
     { 
      var childrenProperty = (childrenSelector.Body as MemberExpression).Member as PropertyInfo; 
      childrenProperty.SetValue(item, collection.AsHierarchy(parentSelector, childrenSelector, item), null); 
     } 
     return items; 
    } 

Następnie można go używać tak:

list.AsHierarchy(x => x.Parent, x => x.Children); 
+1

Witam. Ten fragment wydaje mi się bardzo interesujący, ale jak go przywołać? Nie rozumiem x => x.Parent? Czy ktoś może dać przykład, by wskazać mi właściwy kierunek? – m33

+0

Musisz utworzyć powyższą metodę rozszerzenia w klasie statycznej, aby z niej skorzystać. Pierwszy parametr określa, jak znaleźć węzeł nadrzędny, a drugi parametr, jak uzyskać kolekcję podrzędnych. –