Ich habe eine Entität namens Category und die Entität enthält ein IEnumerable namens ChildCategories. Eine Kategorie kann diese untergeordneten Kategorien haben, die ihre eigenen untergeordneten Kategorien haben können und so weiter.
Angenommen, ich habe die oberste Kategorie ausgewählt, möchte alle untergeordneten Kategorien und ihre untergeordneten Kategorien usw. erhalten, so dass ich alle hierarchischen untergeordneten Elemente der Kategorie habe. Ich will das schmeicheln und mit der Anfangskategorie zurückkehren. Ich habe versucht, etwas wie
zu erstellen %Vor%Nach der Methode SelectMany würde es flacher werden, aber ich habe es nicht verstanden.
In seinem Blogpost Durchstreichen Sie eine hierarchische Struktur mit LINQ-to -Hierarchisch , Arjan Einbu beschreibt eine Methode zur Verflachung von Hierarchien für eine einfachere Abfrage:
Kann ich eine generische Erweiterungsmethode erstellen, die eine Hierarchie abflacht? [...]
Dazu müssen wir analysieren, welche Teile der Methode ausgelagert werden müssen. Das wäre die Knoteneigenschaft des TreeNode. Können wir das auf eine andere Weise erreichen? Ja, ich denke, dass ein Delegierter uns helfen kann, also versuchen wir es:
%Vor%
casperOne beschreibt dies in seiner Antwort , zusammen mit den Problemen, die damit verbunden sind, die Hierarchie direkt mit LINQ zu durchlaufen.
Sie können so etwas nicht mit LINQ alleine machen; LINQ bietet keine Unterstützung für das Durchsuchen einer unbekannten Ebene von Knoten, die sofort einsatzbereit sind.
Außerdem haben Sie keine echte Möglichkeit, die Struktur einzuebnen, die Anzahl der benötigten Eigenschaften ist unbekannt (da sie an die Baumtiefe gebunden ist, die ebenfalls unbekannt ist).
Ich würde empfehlen, Iteratoren in C # zu verwenden, um den Baum zu glätten, etwa so:
%Vor% Dann können Sie die Erweiterungsmethode aufrufen und die Ergebnisse in ein List<T>
; es ist ungefähr so flach, wie du bekommen wirst.
Hinweis: Sie könnten sehr leicht eine StackOverflowException
auslösen, wenn die Hierarchie dies ist tief genug. Zu diesem Zweck möchten Sie wirklich diese nicht-rekursive Methode verwenden:
Die Stack<T>
Instanz befindet sich auf dem Heap und nicht auf dem Aufruf-Stack Sie werden den Callstack-Speicherplatz nicht verlassen.
Sie können Stack<T>
auch in Queue<T>
ändern, wenn Sie anders möchten Semantik zurückgeben (oder Sie können die Kinder auf verschiedene Arten durchlaufen), wenn Sie eine bestimmte Reihenfolge benötigen.
Wenn Sie eine sehr spezifische Reihenfolge benötigen, würde ich nur empfehlen, die Reihenfolge in der Methode zu ändern, wenn Sie eine große Anzahl von Elementen haben, die durchlaufen werden müssen, was den Aufruf von OrderBy
zum Rückgabewert prohibitiv.
Tags und Links .net linq-to-entities