EntityFramework und System.Linq.Dynamic Joining mit Where Expression

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von KSE.

    EntityFramework und System.Linq.Dynamic Joining mit Where Expression

    Hallo zusammen,

    ich habe mir ein Datengenerator gebaut, der über die Where-Extension der Linq.Dynamic einen dynamischen Filter auf eine Gejointe-Liste anwendet.
    Funktioniert auch wunderbar. Das Problem ist jetzt nur, dass alle gejointen Tabellen vollständig geladen werden müssen und erst dann der Where-String angewendet wird, d.h. bei Datensätze > 1000 wird das sehr langsam.

    Weiß jemand wie man das performanter hin bekommt?


    VB.NET-Quellcode

    1. Public Function GetJoiningData(ByVal WhereString As String) As ObservableCollection(Of JoiningGesamtdaten)
    2. Return New ObservableCollection(Of JoiningGesamtdaten)((
    3. From gru In (database.GetAll(Of Basis)())
    4. Join bed In (database.GetAll(Of BedGrunddaten)()) On bed.Grunddaten Equals gru
    5. Join bel In (database.GetAll(Of BelGrunddaten)()) On bel.Grunddaten Equals gru
    6. Join fil In (database.GetAll(Of FilGrunddaten)()) On fil.Grunddaten Equals gru
    7. Join ger In (database.GetAll(Of GefilterGrunddaten)()) On ger.Grunddaten Equals gru
    8. Join lüf In (database.GetAll(Of LfGrunddaten)()) On lüf.Grunddaten Equals gru
    9. Join steu In (database.GetAll(Of StGrunddaten)()) On steu.Grunddaten Equals gru
    10. Join vibverk In (database.GetAll(Of VVerknüpfung)()) On vibverk.Grunddaten Equals gru
    11. Select New JoiningGesamtdaten With {
    12. .Basis = gru,
    13. .BedGrunddaten = bed,
    14. .BelGrunddaten = bel,
    15. .FiGrunddaten = fil,
    16. .GefilterGrunddaten = ger,
    17. .LfGrunddaten = lüf,
    18. .StGrunddaten = steu,
    19. .VVerknpüfungen = vibverk
    20. }).ToList.OrderByDescending(Function(x) x.TestNumber).Where(WhereString).ToList)
    21. End Function
    Gruß von der KSE

    ks-entwicklung.de
    naja - vermutlich ist database.GetAll() teuer - verstehe ich das richtig, dass das eine ganze Tabelle von der Db abruft?
    Und Joins sind auch teuer.
    Ausserdem entstehen bei Joins sehr breite Tabellen, nämlich mit Spalten beider gejointen.
    Und die Anzahl Datensätze entspricht oft der Anzahl der grössten Tabelle.
    Also deine durchsuchten Gesamt-Daten sind ein riesiges riesiges Datenmonster von vielfacher Größe der gesamten Datenbank.
    Also in der Breite hat die durchsuchte Tabelle die Summe aller Breiten aller 8 Tabellen, und in der Länge die Länge der längsten Tabelle.

    Wie du das besser löst, kann ich dir nicht sagen, weil wenn du son Datenmonster brauchst, dann brauchstes halt - ich weiß ja nicht, wozu das gut sein soll.



    Mal andere Frage: Kompiliert das überhaupt?
    Weil .Where(WhereString) scheint mir SyntaxFehler.
    Hi! Du lädst in deiner Funktion alle möglichen Daten, obwohl du bloß eine Handvoll brauchst. Das sieht verdammt nach erste Gehversuche aus. Schau dir mal IQueryable an. Dies führt Serverseitig eine Abfrage aus und du hast nur die Daten, die du brauchst. Das geht bedeutend schneller.
    Hi! Du lädst in deiner Funktion alle möglichen Daten, obwohl du bloß eine Handvoll brauchst. Das sieht verdammt nach erste Gehversuche aus. Schau dir mal IQueryable an. Dies führt Serverseitig eine Abfrage aus und du hast nur die Daten, die du brauchst. Das geht bedeutend schneller.


    Hallo zurück, GetAll ist vom Typ IQueryable, somit sollten eigentlich nur die angeforderten Daten geladen werden. Da ich aber das Where erst nach .toList anwende werden alle Daten geladen. D.h. die Where müsste vorher verwurstelt werden denke ich , aber wie ??
    Gruß von der KSE

    ks-entwicklung.de
    nein, du musst das Tolist und Orderby weglassen. Die erzwingen beide, dass das komplette Datenmonster gezogen wird.
    Und dann solltest du das Sql-Logging aktivieren, von EF kenne ich das, dass man einstellen kann, dass die generierten Queries ins Ausgabefenster geloggt werden.
    Da kann man dann wirklich abschätzen, was passiert, und wo die Performance verbrannt wird.

    Und nachwievor kauf ich dir das ganze Gesumse ühaupt nicht ab, weil

    ErfinderDesRades schrieb:

    Mal andere Frage: Kompiliert das überhaupt?
    Weil .Where(WhereString) scheint mir SyntaxFehler.

    Mal andere Frage: Kompiliert das überhaupt?Weil .Where(WhereString) scheint mir SyntaxFehler.


    Deswegen die System.Linq.Dynamic.dll über NuGet-Package. Diese Erweiterung ermöglicht,dass man einen String in Where packen kann z.B. TestNumber=15000
    Typisiert wäre es ja dann .Where(Function(x) x.TestNumber=15000) .


    Habe es jetzt so probiert:

    VB.NET-Quellcode

    1. Public Function GetJoiningData(ByVal WhereString As String) As ObservableCollection(Of JoiningGesamtdaten)
    2. Return New ObservableCollection(Of JoiningGesamtdaten)((
    3. From gru In (database.GetAll(Of Grunddaten)())
    4. Join bed In (database.GetAll(Of BedienteilGrunddaten)()) On bed.Grunddaten Equals gru
    5. Join bel In (database.GetAll(Of BeleuchtungGrunddaten)()) On bel.Grunddaten Equals gru
    6. Join fil In (database.GetAll(Of FilterGrunddaten)()) On fil.Grunddaten Equals gru
    7. Join ger In (database.GetAll(Of GeruchsfilterGrunddaten)()) On ger.Grunddaten Equals gru
    8. Join lüf In (database.GetAll(Of LüfterGrunddaten)()) On lüf.Grunddaten Equals gru
    9. Join steu In (database.GetAll(Of SteuerungGrunddaten)()) On steu.Grunddaten Equals gru
    10. Join vibverk In (database.GetAll(Of VIBVerknüpfung)()) On vibverk.Grunddaten Equals gru
    11. Select New JoiningGesamtdaten With {
    12. .Grunddaten = gru,
    13. .BedienteilGrunddaten = bed,
    14. .BeleuchtungGrunddaten = bel,
    15. .FilterGrunddaten = fil,
    16. .GeruchsfilterGrunddaten = ger,
    17. .LüfterGrunddaten = lüf,
    18. .SteuerungGrunddaten = steu,
    19. .VIBVerknpüfungen = vibverk
    20. }).Where(WhereString).ToList) '.Take(100)
    21. End Function



    Bekomme jetzt aber folgenden Fehler:

    The specified type member 'TestNumber' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
    Gruß von der KSE

    ks-entwicklung.de