Ich arbeite mit C # und .NET Framework 4.5.1 und rufe mit Entity Framework 6.1.3 Daten aus einer SQL Server-Datenbank ab.
Ich habe das:
codes = codesRepo.SearchFor(predicate)
.Select(c => new Tuple<string, byte>(c.Id, c.Flag))
.ToList();
Und wenn ich es starte, bekomme ich folgende Nachricht:
In LINQ to Entities werden nur parameterlose Konstruktoren und Initialisierer unterstützt.
Ich weiß nicht, wie ich das Tupel erstellen muss, da alle Beispiele, die ich gefunden habe, größtenteils wie dieses sind.
Ich habe das versucht:
codes = codesRepo.SearchFor(predicate)
.Select(c => Tuple.Create(c.Id, c.Flag))
.ToList();
Und erhalten Sie diesen Fehler:
LINQ to Entities erkennt die Methode 'System.Tuple`2 [System.String, System.Byte] Create [String, Byte] (System.String, Byte)' nicht und diese Methode kann nicht in einen Speicherausdruck übersetzt werden.
Wo ist das Problem?
c#
entity-framework
linq
tuples
VansFannel
quelle
quelle
Antworten:
Während die Antwort von octavioccl funktioniert, ist es besser, zuerst das Abfrageergebnis in einen anonymen Typ zu projizieren und dann zu enumerable zu wechseln und es in tuple zu konvertieren. Auf diese Weise ruft Ihre Abfrage nur die benötigten Felder aus der Datenbank ab.
Hinweis: Die obige Regel gilt für EF6. EF Core unterstützt natürlich Tupel (in Projektion oder als Join- / Gruppenschlüssel) über den Tupelkonstruktor, z. B. funktioniert die ursprüngliche Abfrage einfach
aber nicht die
Tuple.Create
Methode (EF Core 2.x).quelle
.Select(c => new { c.Id, c.Flag, c.Foo?.Code })
funktioniert nicht.?.
wird in Ausdrucksbäumen nicht unterstützt. Ansonsten können Sie den anonymen Typ mit beliebig vielen Werten erweitern - vergessen Sie nicht, sie bei Bedarf zu benennen :) zBc => new { c.Id, c.Flag, Code = (int?)c.Foo.Code }
Nur eine aktualisierte Antwort für C # 7, jetzt können Sie eine einfachere Syntax verwenden, um ValueTuples zu erstellen.
Sie können jetzt sogar die Eigenschaften des Tupels benennen:
Anstatt es als Item1 oder Item2 zu verwenden, können Sie als Id oder Flag darauf zugreifen.
quelle
In linq to entity können Sie auf einen anonymen Typ oder auf ein DTO projizieren. Um dieses Problem zu vermeiden, können Sie die
AsEnumerable
Erweiterungsmethode verwenden:Mit dieser Methode können Sie mit der Arbeit Linq to Object statt Linq to Entities , so nach dem es nennen, können Sie das Ergebnis der Abfrage im Projekt , was Sie need.The Vorteil der Verwendung
AsEnumerable
stattdessenToList
wird , dassAsEnumerable
sich die Abfrage nicht ausgeführt werden , es Ausführung latenten bewahrt. Es ist eine gute Idee, Ihre Daten immer zuerst zu filtern, bevor Sie eine dieser Methoden aufrufen.quelle
Versuche dies:
Wurde informiert, dass dies in LINQ für Entitäten nicht akzeptiert wird.
Eine andere Möglichkeit wäre, das Ergebnis vor der Auswahl in den Speicher zu ziehen. Wenn Sie dies tun, würde ich empfehlen, die gesamte Filterung vor .AsEnumerable () durchzuführen, da dies bedeutet, dass Sie nur die gewünschten Ergebnisse zurückziehen, anstatt die gesamte Tabelle zurückzuziehen und dann zu filtern.
Außerdem kann Tuple.Create (c.Id, c.Flag) in neues Tuple (c.Id, c.Flag) geändert werden, wenn Sie den Code in den Tupeltypen etwas expliziter gestalten möchten
quelle
Ich habe die Antwort gefunden:
quelle
Verwenden Sie dazu diese Methode und verwenden Sie den Async.
quelle
Nur meine zwei Cent: Das hat mich ein paar Mal mit den Typnamen erwischt:
Ein paar knifflige Beispiele:
Grüße.
quelle
public (string Id, byte Flag) SearchFor(Expression predicate)
, aber das ist nebensächlich. Zwei Cent sollten keine Antwort sein, sondern ein Kommentar.