Ich habe eine SQL-Ansicht, die eine Antwort mit 8 Spalten erzeugt. Es ist ziemlich kompliziert, deshalb werde ich es hier nicht aufführen und es wird nicht viel zu dem Thema beitragen, das ich versuche zu verstehen.
Wenn ich die Ansicht in SQL Manager direkt mit dieser Abfrage abfrage
%Vor%Ich bekomme das erwartete Ergebnis von (Die ersten beiden Zeilen sind wichtig)
%Vor%Wenn ich den folgenden LINQ gegen die Ansicht
führe %Vor%Ich bekomme tatsächlich
%Vor%wie Sie sehen können, sind die ersten beiden Einträge identisch und die Unterscheidung der ID (32575 und 32576) ist verloren gegangen.
Wenn ich den SQL-Profiler anschaue, wenn ich die LINQ-Abfrage für die Ansicht ausführe, wird das folgende SQL
erzeugt %Vor%und wenn ich das dann direkt in SQL Manager ausführe bekomme ich das gewünschte Ergebnis von:
%Vor%Da irgendjemand eine Idee hatte, was hier geschehen könnte und warum die Ausführung der LINQ-Anfrage ein anderes Ergebnis liefert als in SQL, aber beim Ausführen des von der LINQ-Abfrage erzeugten SQL das gewünschte Ergebnis liefert?
Was macht SQL, wenn es direkt verwendet wird, was LINQ bei korrekter Darstellung nicht tut?
Eigentlich haben die Fragen von @stanke mir eine Idee gegeben.
Ich habe die Ansicht tatsächlich geringfügig geändert, um eine weitere Spalte hinzuzufügen, so dass jeder Datensatz eindeutig identifiziert werden kann.
Ich brauche den Spaltenwert in meiner resultierenden Tabelle eigentlich nicht, aber er half LINQ, die Datensätze beim Abfragen eindeutig zu halten. Es sieht so aus, als würde SQL das alleine gut machen, aber LINQ brauchte ein bisschen Hilfe, um die Datensätze zu unterscheiden.
Es funktioniert nun wie erwartet in SQL und LINQ
Ihr Problem ist ähnlich wie folgt: Verwenden einer Ansicht ohne Primärschlüssel mit Entität
Geben Sie den Schlüssel s an, der Ihre Zeile eindeutig macht. Sie können diese Schlüssel in Ihrer Entitätszuordnung über Attribute angeben:
%Vor%Oder Sie können es über den Code-Ansatz tun:
%Vor%Wenn der Schlüssel, den das Entitätsframework für die Ansicht auswählt, nicht eindeutig ist, werden die Ergebnisse möglicherweise nicht korrekt zurückgegeben.
Manchmal sind Tasten nicht dazu geeignet, bestimmte Ansichten zu konsumieren. Für diese Fälle kann ein gefälschter "Schlüssel" hinzugefügt werden, der nur ein Zeilenzähler ist:
%Vor%Definieren Sie dies manuell über die EF Edmx-Schnittstelle als Schlüssel.
Wenn Sie mehrmals in der Ansicht auswählen, wird möglicherweise nicht die gleiche Reihenfolgenreihenfolge angegeben (und es können Lücken auftreten), sodass sie nicht für die tatsächliche Verfolgung verwendet werden sollte. Beachten Sie, dass die Verwendung einer echten "Bestellung von" die Abfrage erheblich verlangsamen kann.
Update (März 2018):
Ich traf einen Fall, in dem die obige Empfehlung die Ansicht immens verlangsamte, wenn man sich gegen ein einfaches Prädikat wandte. Ich denke, der Grund war, dass die Ansicht innerhalb einer Unterabfrage eine Top / Order hatte, so dass die Engine dachte, dass sie die vollständige Lösungsmenge berechnen musste.
Um dies zu vermeiden, sollten Sie linQ AsNoTracking () mit solchen Ansichten ( link ) verwenden. Mit AsNoTracking () kann jede Nicht-Null-Spalte als Primärschlüssel in EF "definiert" werden. Wenn es kein Nicht-Null-Feld gibt oder Sie einen expliziten falschen "Schlüssel" definieren möchten, betrachten Sie diesen noch einfacheren Ansatz:
%Vor%In der 6. Spalte der ersten beiden Zeilen haben Sie den gleichen Wert - 124, was dazu führen kann, dass eine Zeile gefiltert wird, wenn dies in dieser Ansicht ein Fremdschlüssel ist. Ich hatte eine ähnliche Situation mit der Load-Funktion der Datentabelle, weil sie beim Laden der abgerufenen Daten in die Datentabelle Constraints anwendet. Versuchen Sie, den Schlüssel von linq nach sql schema zu entfernen.