LINQ-Verbindung mit IEnumerable
konstante Sammlung
Bei Verwendung einer LINQ JOIN-Klausel innerhalb einer SELECT-Anweisung einer anderen JOIN-Anweisung tritt der Fehler „Es kann kein konstanter Wert vom Typ API.Models.PersonProtocol erstellt werden. In diesem Kontext werden nur primitive oder aufgezählte Typen unterstützt“ auf. Dieser Fehler tritt auf, weil die IEnumerable
CollectionppCombined
nicht als konstanter Wert in einem Datenbankkontext verwendet werden kann.
Im bereitgestellten Code:
<code class="language-csharp">var persons = db.Favorites .Where(x => x.userId == userId) .Join(db.Person, x => x.personId, y => y.personId, (x, y) => new PersonDTO { personId = y.personId, addressId = y.addressId, favoriteId = x.favoriteId, personProtocol = (ICollection<PersonProtocol>) ppCombined .Where(a => a.personId == x.personId) .Select( b => new PersonProtocol() { personProtocolId = b.personProtocolId, activateDt = b.activateDt, personId = b.personId }) });</code>
Dieser Code versucht, Daten aus den Tabellen db.Favorites
und db.Person
zu verketten und projiziert das Ergebnis dann in ein PersonDTO
-Objekt. Innerhalb des PersonDTO
-Objekts gibt es eine personProtocol
-Eigenschaft, die auf das Ergebnis einer LINQ-Abfrage für die ppCombined
-Sammlung festgelegt wird.
Das Problem besteht darin, ppCombined
als konstanten Wert in einem Datenbankkontext zu verwenden. ppCombined
ist ein im Speicher erstelltes IEnumerable
-Objekt, keine Datenbanktabelle. Beim Ausführen einer LINQ-Abfrage wird versucht, die personProtocol
-Projektion in eine SQL-Anweisung zu konvertieren. Dies ist jedoch nicht möglich, da ppCombined
keine Datenbanktabelle oder kein primitiver Typ ist.
Lösung
Um diesen Fehler zu beheben, können wir die gefilterten Elemente in ppCombined
im Speicher abrufen, nachdem wir andere Attribute aus der Datenbank abgerufen haben. Das Folgende ist der geänderte 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() // 数据库查询在此结束,其余部分是在内存中进行的查询 .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>
In diesem geänderten Code endet die Datenbankabfrage mit der Methode AsEnumerable()
. Dies bedeutet, dass der Rest der Operation vollständig im Speicher ausgeführt wird. Filtern Sie dann in einer speicherbasierten Select
-Projektion des anonymen Objekts die ppCombined
-Sammlung und konvertieren Sie sie in eine Liste.
Durch die Trennung der Datenbankabfrage von der In-Memory-Verarbeitung vermeiden wir das Problem der Übergabe von In-Memory-Sammlungen an den Datenbankkontext und lösen so den Fehler.
Das obige ist der detaillierte Inhalt vonWie behebe ich den Fehler „Es kann kein konstanter Wert erstellt werden' in LINQ JOIN mit IEnumerable Constant Collection?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!