Verwenden Linq für Terminal- / Blattknoten in einer hierarchischen Tabelle / Kompositum-Muster zu Abfrage

StackOverflow https://stackoverflow.com/questions/414945

Frage

Ich habe eine selbst verweisende Tabelle mit einer ID, Kategorie und ParentId. Es ist ein typisches Szenario einer Hierarchietabelle von Kategorien, die sie in Kategorien eingeteilt werden können, die DB-Experten sagen Sie mir das adjacency Modell genannt wird.

Was ich will, ist Linq to SQL verwenden für Unterkategorien abzufragen, die sich ohne weitere Unterkategorien verbunden sind, das heißt, sie sofort Blattknoten von einer gegebenen Kategorie oder Unterkategorie sind.

Der einfache Teil, bekam ich, was die Unterkategorien nur erhält. Fast verlegen da, um den Code zu setzen. Aber wir möchten den Code sehen ..

IList<Categories> subcategories = context.Where( c => c.ParentId == 1).ToList();  

Aber es Kategorien ohne Unterkategorien Verengung dreht sie um. Jede Hilfe wäre sehr geschätzt.

Danke für deine Hilfe. Jeff

UPDATE ** Es scheint, das funktioniert, aber wenn jemand konnte bestätigen, dass es „richtige“ ist würde ich dankbar sein. Also, wenn ich Endknoten unter einer Kategorie mit Id will = 1, ich würde das tun:

Categories.Where( c => !c.Children.Any ( d => d.ParentId == c.Id)).Where( e => e.ParentId == 1) 

"Kinder" ist der Name Linq die sich selbst verweisende Vereinigung gibt.

War es hilfreich?

Lösung

Ihre Lösung ist richtig, weil die Any() Methode in SQL übersetzt „exists ()“ Funktion und !c.Children.Any ( d => d.ParentId == c.Id)) übersetzt in eine SQL-Klausel ähnlich wie NOT EXISTS (SELECT * FROM Categories WHERE ParentID = outerRef.ID)

Eine andere Möglichkeit, es zu tun ist Count zu verwenden:

Categories.Where( c => c.Children.Count(d => d.ParentId == c.Id) == 0).Where( e => e.ParentId == 1)

Aber in der Regel exists () wird bevorzugt () in SQL zu COUNT (aus Leistungsgründen), so dass die Lösung mit Any () soll die richtige sein.

Andere Tipps

Ich denke, wenn ich Ihre Frage richtig verstanden alle der untergeordneten Elemente bekommen Sie versuchen, die keine Kinder dort selbst haben ... diese Abfrage selbst schließt sich an sich um die Tabelle zu testen, ob der Knoten als Eltern verwendet wird wenn es dann nicht ist, ist es im Ergebnis angezeigt werden.

Ich bin nicht sicher, ob das funktioniert, wie ich nichts, es zu testen auf ...

   (from c in context
    join cc in context on c.id equals cc.parentid into temp
    from t in temp.DefaultIfEmpty()
    where t == null
    select c).ToList()
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top