Ich verwende LINQ zu Entitäten, um seitenweise Ergebnisse anzuzeigen. Aber ich habe Probleme mit der Kombination von Skip()
, Take()
und OrderBy()
Anrufe.
Alles funktioniert gut, außer dass OrderBy()
zu spät zugewiesen wird. Es wird ausgeführt, nachdem die Ergebnismenge um Skip()
und Take()
reduziert wurde.
So hat jede Seite der Ergebnisse Elemente in Reihenfolge. Aber die Bestellung erfolgt auf einer Seite mit einer Handvoll Daten, anstatt die gesamte Menge zu bestellen und diese Datensätze dann mit Skip()
und Take()
zu begrenzen.
Wie setze ich mit diesen Anweisungen Vorrang?
Eine mögliche Lösung wäre, den gruppierten Index auf die Reihenfolge nach Spalte anzuwenden, aber diese Spalte ändert sich häufig, was die Datenbankleistung bei Einfügungen und Aktualisierungen verlangsamen würde. Und das will ich wirklich nicht.
Ich habe ToTraceString()
auf meiner Abfrage ausgeführt, wo wir sehen können, wann die Reihenfolge nach auf die Ergebnismenge angewendet wird. Leider am Ende. : (
Ich habe es geschafft, dieses Problem zu umgehen. Versteh mich nicht falsch hier. Ich habe das Präzedenzproblem noch nicht gelöst, aber ich habe es gemildert.
Was ich getan habe?
Dies ist der Code, den ich benutzt habe, bis ich eine Antwort von Devart bekomme. Wenn sie dieses Problem nicht lösen können, muss ich diesen Code am Ende verwenden.
%Vor%Als Erstes bekomme ich die IDs meiner Entitäten geordnet. Nur IDs zu erhalten ist auch bei größeren Datenmengen gut performant. MySql-Abfrage ist recht einfach und funktioniert sehr gut. Im zweiten Teil partitioniere ich diese IDs und verwende sie, um tatsächliche Entity-Instanzen zu erhalten.
Wenn Sie darüber nachdenken, sollte es noch besser funktionieren, als ich es am Anfang getan habe (wie in meiner Frage beschrieben), weil das Erhalten der Gesamtzählung aufgrund der vereinfachten Abfrage viel schneller ist. Der zweite Teil ist praktisch sehr sehr ähnlich, nur dass meine Entitäten eher durch ihre IDs zurückgegeben werden als durch partitioniert mit Skip
und Take
...
Hoffentlich findet jemand diese Lösung hilfreich.
Ich habe nicht direkt mit Linq an Entitäten gearbeitet, aber es sollte eine Möglichkeit geben, bestimmte gespeicherte Prozeduren bei Bedarf an bestimmten Orten anzuhängen. (Linq to SQL tat.) Wenn ja, könnten Sie diese Abfrage in eine gespeicherte Prozedur verwandeln, die genau das tut, was benötigt wird, und dies effizient tun.
Sind Sie absolut sicher, dass die Bestellung aus ist? Wie sieht das SQL aus?
Können Sie Ihren Code wie folgt neu anordnen und die Ausgabe veröffentlichen?
%Vor%Bearbeiten:
Ich bin mir absolut sicher. Sie können meine "Bearbeitung" überprüfen, um das Trace-Ergebnis meiner Abfrage mit übersprungenem Trace-Ergebnis zu sehen, das in diesem Fall zwingend erforderlich ist. Graf ist nicht wirklich wichtig.
Ja, ich sehe es. Wow, das ist ein Stümper. Könnte sogar ein echter Käfer sein. Ich stelle fest, dass Sie nicht SQL Server verwenden ... Welche DB verwenden Sie? Sieht so aus, als wäre es MySQl.
Wenn Sie von Ihnen kommentieren, ist das Fortbestehen der Werte in einer Liste nicht akzeptabel:
Es gibt keine Möglichkeit, die Iterationen vollständig zu minimieren, wie Sie es beabsichtigt haben (und ich hätte es auch versucht, in der Hoffnung zu leben). Es wäre nett, die Iterationen um eins zu reduzieren. Ist es möglich, den Count nur einmal zu holen und zu cachen / Session zu machen? Dann könnten Sie:
%Vor%Hoffentlich kannst du den Count irgendwie zwischenspeichern oder vermeiden, ihn jedes Mal zu brauchen. Selbst wenn Sie nicht können, ist dies das Beste, was Sie tun können.
Könnten Sie bitte ein Beispiel zur Veranschaulichung des Problems erstellen und es an uns senden (Support * devart * com, Betreff "EF: Skip, Take, OrderBy")?
Ich hoffe, wir können Ihnen helfen.
Sie können uns auch über unsere Foren oder Kontaktformular .
Eine Möglichkeit:
%Vor%Konvertiere es vor dem Überspringen in eine Liste. Es ist nicht zu effizient, wohlgemerkt ...
Tags und Links linq mysql linq-to-entities devart dotconnect