Ich versuche, eine verschachtelte Abfrage mit Linq/LinqKit zu erstellen. In der Theorie scheint das einfach zu sein. Aber ich bin mit dem praktischen Teil festgefahren.StackOverflowException mit Linq (Kit) für verschachtelte Daten
In meiner Datenbank habe ich eine Tabelle, die eine Selbstreferenz auf ihre Eltern hat. In meiner linq-Abfrage möchte ich nun alle Eltern eines bestimmten Elements (und die Eltern dieses Elements usw.) auswählen.
In meinem Code habe ich den folgenden Ausdruck in Teilklasse MyTable
:
public static Expression<Func<MyTable, IEnumerable<MyTable>>> Parents => (entity) => entity.ParentId != null ? new[]{entity.ParentEntity}.Union(Parents.Invoke(entity.ParentEntity) : new MyEntity[]{};
, die die Eltern einer bestimmten Einheit und jene Eltern wählen sollte, wenn die ParentId
eingestellt ist.
Die Abfrage selbst (vereinfachte):
dbContext
.MyTable
.AsExpandable()
.Where(x => x.Id == myId)
.Select(x => new
{
Parents = MyTable.Parents.Invoke(x, dbContext)
});
diesen Code Lauf endet in einem StackOverflowException
auf, als die Stop-Bedingung nicht getroffen wird und damit der Parents
-Aufruf verschachtelt ist endlos, bis der Stapel voll ist.
Irgendwelche Ideen wie das gemacht werden kann oder ist das nicht möglich? Oder gibt es eine andere Möglichkeit, verschachtelte Daten mit Linq
/LinqKit
innerhalb einer Abfrage abzurufen?
ich schon versucht, den Kontext zu dem Ausdruck, um eine Unterabfrage (auch nicht funktioniert) zu erstellen vorbei: in den Kommentaren
public static Expression<Func<MyTable, MyContext, IEnumerable<MyTable>>> Parents => (entity, dbContext) => entity.ParentId != null ? new[]{entity.ParentEntity}.Union(Parents.Invoke(dbContext.MyTable.FirstOrDefault(x => x.Id == entity.ParentId), dbContext) : new MyEntity[]{};
Hallo, interessanter Versuch! Aber nein, es ist nicht möglich, einen erweiterbaren (EF-kompatiblen) rekursiven Ausdruck mit unbekannter maximaler Verschachtelungsebene zu erstellen, da es kein Äquivalent zu SQL CTE gibt. –
@IvanStoev, Was wäre, wenn ich die maximale Verschachtelungstiefe kennen würde? Bereits versucht, einen Tiefenparameter zu übergeben, der durch jeden rekursiven Aufruf dekrementiert wird. Aber die gleiche Ausnahme hier – KingKerosin