Hierarchy Problem -> Ersetzen Rekursion mit Linq Mitglied werden?
-
07-07-2019 - |
Frage
Ich habe eine selbstReferenzTabelle, die ID hat, ParentID (nullable).
So wird die Tabelle viele Knoten enthält, wobei jeder Knoten die Wurzel in der Hierarchie sein könnte (parent ist Null) oder jede Ebene der Hierarchie (parent existiert an anderer Stelle in der Tabelle).
ein beliebiger Ausgangsknoten Da gibt es eine elegante Linq-Abfrage, die alle Kinder der Hierarchie von diesem Knoten zurückkehren wird?
Danke.
Lösung
Wenn Sie möchten, wählen Sie alle direkten Kinder eines Knotens, eine einfache Abfrage wie die folgende sollte die Arbeit machen:
from item in table
where item.ID == parentID;
select item
Wenn Sie auswählen möchten, alle Nachkommen eines Knotens, ist dies nicht möglich, mit LINQ, weil es Rekursion oder einen Stapel erfordert, die LINQ (und SQL) nicht bieten.
Siehe auch:
- Stackoverflow: LINQ für sich selbst verweisende Tabellen SQL ?
- Codeproject: T-SQL - Wie alle Nachkommen eines bestimmten Elements in einer erhalten hierarchische Tabelle
- Stackoverflow: Rekursion in LINQ Ausdruck
Andere Tipps
Hier ist ein kurzer, die ich gerade geschrieben:
class MyTable
{
public int Id { get; set; }
public int? ParentId { get; set; }
public MyTable(int id, int? parentId) { this.Id = id; this.ParentId = parentId; }
}
List<MyTable> allTables = new List<MyTable> {
new MyTable(0, null),
new MyTable(1, 0),
new MyTable(2, 1)
};
Func<int, IEnumerable<MyTable>> f = null;
f = (id) =>
{
IEnumerable<MyTable> table = allTables.Where(t => t.Id == id);
if (allTables
.Where(t => t.ParentId.HasValue && t.ParentId.Value == table
.First().Id).Count() != 0)
return table
.Union(f(
allTables.Where(t => t.ParentId.HasValue && t.ParentId.Value == table
.First().Id).First().Id));
else return table;
};
Aber ich glaube, dass es möglich ist, SQL mit einer Union ALL zu tun verwenden.
Ich weiß, dass dies eine alte Post, aber Sie sollten diese Erweiterung finden Sie unter:
http://www.scip.be/index.php?Page=ArticlesNET23
Ich habe mit worden, und es funktioniert super.
Im Grunde bin ich mit so etwas wie dies geht, wie diskutiert in der SO verknüpfen Sie proivded.
public IQueryable GetCategories(Category parent)
{
var cats = (parent.Categories);
foreach (Category c in cats )
{
cats = cats .Concat(GetCategories(c));
}
return a;
}
CTEs ist wahrscheinlich die beste Lösung, aber ich würde gerne Dinge für heute in der gleichen Ebene halten.