Fehlerbehebung bei LINQ-Joins und In-Memory-Sammlungen
Der Fehler „Konstanter Wert vom Typ kann nicht erstellt werden... In diesem Kontext werden nur primitive Typen oder Aufzählungstypen unterstützt“ erscheint häufig, wenn versucht wird, eine In-Memory-Sammlung (wie ppCombined
in diesem Beispiel) direkt einzubinden in eine Datenbank-LINQ-Abfrage. Dies liegt daran, dass Datenbankabfragen ausschließlich auf datenbankresidenten Daten basieren. Die Verknüpfung mit In-Memory-Daten wird nicht direkt unterstützt.
Das Problem manifestiert sich typischerweise in der Select
-Klausel der Join
-Anweisung. Der Versuch, ein PersonDTO
-Objekt zu erstellen, einschließlich einer aus der In-Memory-Sammlung gefüllten Eigenschaft, verursacht den Konflikt.
Die Hauptursache für den LINQ JOIN-Fehler
Der Fehler entsteht durch den Versuch, einen Filtervorgang (Where
-Klausel) für die ppCombined
-Sammlung innerhalb der Select
-Anweisung der Datenbankabfrage durchzuführen. Die Datenbank-Engine kann diesen In-Memory-Vorgang nicht in sein eigenes Äquivalent übersetzen.
Lösung: Separate Datenbank- und In-Memory-Operationen
Die Lösung besteht darin, die Datenbankabfrage von der In-Memory-Verarbeitung zu trennen. Dazu gehört zunächst die Ausführung der Datenbankabfrage und anschließend die Filterung und Datenbearbeitung des resultierenden In-Memory-Datensatzes. Die AsEnumerable()
-Methode ist hier der Schlüssel. Es erzwingt die Ausführung der Datenbankabfrage und gibt die Ergebnisse als IEnumerable
-Objekt zurück, sodass nachfolgende Vorgänge vollständig im Speicher ausgeführt werden können.
Hier ist der korrigierte Code:
<code class="language-csharp">var persons = db.Favorites .Where(f => f.userId == userId) .Join(db.Person, f => f.personId, p => p.personId, (f, p) => new { personId = p.personId, addressId = p.addressId, favoriteId = f.favoriteId }) .AsEnumerable() // Database query completes here .Select(x => new PersonDTO { personId = x.personId, addressId = x.addressId, favoriteId = x.favoriteId, personProtocol = ppCombined .Where(p => p.personId == x.personId) .Select(p => new PersonProtocol { personProtocolId = p.personProtocolId, activateDt = p.activateDt, personId = p.personId }) .ToList() });</code>
Durch die Verwendung von AsEnumerable()
wird die Datenbankabfrage abgeschlossen und die nachfolgende Select
-Anweisung arbeitet ausschließlich mit den aus der Datenbank abgerufenen Daten, wodurch die Inkompatibilität mit der speicherinternen ppCombined
-Sammlung behoben wird. Dadurch wird sichergestellt, dass die Abfrage erfolgreich ausgeführt wird.
Das obige ist der detaillierte Inhalt vonWarum schlägt mein LINQ JOIN fehl, wenn ich eine In-Memory-Sammlung verwende?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!