Mam następujący kod:
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);
I pojawia się ten błąd, gdy próbuję uruchomić kod:
LINQ to Entities nie rozpoznaje metody „Boolean IsNullOrWhiteSpace (System.String)” i nie można jej przetłumaczyć na wyrażenie magazynu. "
Jak mogę rozwiązać ten problem i napisać kod lepiej niż to?
List<string> my = new List<string>(); var i = from m in my where !string.IsNullOrWhiteSpace(m) select m;
W takim przypadku ważne jest, aby rozróżnić
IQueryable<T>
iIEnumerable<T>
. W skrócieIQueryable<T>
jest przetwarzany przez dostawcę LINQ w celu dostarczenia zoptymalizowanego zapytania. Podczas tej transformacji nie wszystkie instrukcje C # są obsługiwane, ponieważ nie jest możliwe przetłumaczenie ich na zapytanie specyficzne dla zaplecza (np. SQL) lub ponieważ implementujący nie przewidział potrzeby tej instrukcji.W przeciwieństwie
IEnumerable<T>
jest wykonywany w stosunku do konkretnych obiektów i dlatego nie zostanie przekształcony. Tak więc jest dość powszechne, że konstrukcje, które są używane zIEnumerable<T>
, nie mogą być używane z,IQueryable<T>
a takżeIQueryables<T>
te obsługiwane przez różnych dostawców LINQ nie obsługują tego samego zestawu funkcji.Istnieją jednak pewne obejścia (takie jak odpowiedź Phila ), które modyfikują zapytanie. Ponadto, jako bardziej ogólne podejście, można cofnąć się do
IEnumerable<T>
przed kontynuowaniem specyfikacji zapytania. Może to jednak mieć negatywny wpływ na wydajność - szczególnie podczas używania go na ograniczeniach (np. Klauzule gdzie). W przeciwieństwie do tego, gdy zajmujemy się transformacjami, wydajność jest dużo mniejsza, a czasami nawet nie istnieje - w zależności od zapytania.Więc powyższy kod można również przepisać w ten sposób:
UWAGA: ten kod będzie miał większy wpływ na wydajność niż odpowiedź Phila . Jednak pokazuje zasadę.
źródło
Użyj gościa wyrażenia, aby wykryć odwołania do string.IsNullOrWhiteSpace i rozbić je na prostsze wyrażenie
(x == null || x.Trim() == string.Empty)
.Poniżej znajduje się rozszerzony użytkownik i metoda rozszerzenia, aby z niego skorzystać. Nie wymaga specjalnej konfiguracji, po prostu wywołaj WhereEx zamiast Where.
Więc jeśli uruchomisz
myqueryable.WhereEx(c=> !c.Name.IsNullOrWhiteSpace())
, zostanie przekonwertowany na!(c.Name == null || x.Trim() == "")
przed przekazaniem do cokolwiek (linq do sql / entity) i przekonwertowany na sql.źródło
Możesz również użyć tego, aby sprawdzić, czy nie ma białych znaków:
źródło
zgłosi wyjątek, jeśli
b.Diameter
jestnull
.Jeśli nadal chcesz użyć swojego wyciągu, lepiej użyj tego czeku
źródło