Ich habe folgenden Code:
return this.ObjectContext.BranchCostDetails.Where(
b => b.TarrifId == tariffId && b.Diameter == diameter
|| (b.TarrifId==tariffId && !string.IsNullOrWhiteSpace(b.Diameter))
|| (!b.TarrifId.HasValue) && b.Diameter==diameter);
Und ich bekomme diesen Fehler, wenn ich versuche, den Code auszuführen:
LINQ to Entities erkennt die Methode 'Boolean IsNullOrWhiteSpace (System.String)' nicht und diese Methode kann nicht in einen Speicherausdruck übersetzt werden. "
Wie kann ich dieses Problem lösen und Code besser schreiben?
List<string> my = new List<string>(); var i = from m in my where !string.IsNullOrWhiteSpace(m) select m;
In diesem Fall ist es wichtig, zwischen
IQueryable<T>
und zu unterscheidenIEnumerable<T>
. ZusamenfassendIQueryable<T>
wird von einem LINQ-Anbieter verarbeitet, um eine optimierte Abfrage zu liefern. Während dieser Umwandlung werden nicht alle C # -Anweisungen unterstützt, da sie entweder nicht in eine Back-End-spezifische Abfrage (z. B. SQL) übersetzt werden können oder weil der Implementierer die Notwendigkeit der Anweisung nicht vorausgesehen hat.Im Gegensatz dazu
IEnumerable<T>
wird gegen die konkreten Objekte ausgeführt und wird daher nicht transformiert. Daher ist es durchaus üblich, dass Konstrukte, mit denen verwendet werdenIEnumerable<T>
kann, nicht verwendet werden könnenIQueryable<T>
undIQueryables<T>
die von verschiedenen LINQ-Anbietern unterstützt werden, nicht dieselben Funktionen unterstützen.Es gibt jedoch einige Problemumgehungen (wie Phils Antwort ), die die Abfrage ändern. Als allgemeinerer Ansatz ist es auch möglich, auf ein zurückzugreifen
IEnumerable<T>
bevor Sie mit der Spezifikation der Abfrage fortfahren. Dies kann jedoch zu Leistungseinbußen führen - insbesondere bei Verwendung für Einschränkungen (z. B. where-Klauseln). Im Gegensatz dazu ist der Leistungseinbruch bei Transformationen viel geringer, manchmal sogar nicht vorhanden - abhängig von Ihrer Abfrage.Der obige Code könnte also auch folgendermaßen umgeschrieben werden:
HINWEIS: Dieser Code hat eine höhere Auswirkung auf die Leistung als Phils Antwort . Es zeigt jedoch das Prinzip.
quelle
Verwenden Sie einen Ausdrucksbesucher, um Verweise auf string.IsNullOrWhiteSpace zu erkennen und in einen einfacheren Ausdruck zu zerlegen
(x == null || x.Trim() == string.Empty)
.Im Folgenden finden Sie einen erweiterten Besucher und eine Erweiterungsmethode, um davon Gebrauch zu machen. Für die Verwendung ist keine spezielle Konfiguration erforderlich. Rufen Sie einfach WhereEx anstelle von Where auf.
Wenn Sie es also ausführen
myqueryable.WhereEx(c=> !c.Name.IsNullOrWhiteSpace())
, wird es in konvertiert,!(c.Name == null || x.Trim() == "")
bevor es an was auch immer übergeben wird (linq in sql / entity) und in sql konvertiert.quelle
Sie können dies auch verwenden, um nach Leerzeichen zu suchen:
quelle
wird eine Ausnahme auslösen, wenn dies der Fall
b.Diameter
istnull
.Wenn Sie Ihre Anweisung dennoch verwenden möchten, verwenden Sie diese Prüfung besser
quelle