Używam ASP.NET MVC 4 i Entity Framework 6 (Kod Po pierwsze) i mam dziwne zachowanie, którego nie chcę/lubię:
Mam klasę klasy Images
, która ma właściwość boolowską IsDeleted
, a teraz chciałbym uzyskać pierwsze 25 obrazów, które nie są usunięte, więc użyłem następujących Kod:.W przypadku (i =>! I.IsDeleted) nie jest tłumaczone na SQL, ale .Where (i => i.IsDeleted.Equals (false)) ma
IEnumerable<Image> items = db.Images.Where(i => !i.IsDeleted).Take(25);
Jak to był bardzo powolny badałem głębiej i okazało się, że Where(i => !i.IsDeleted)
już wyzwala zapytanie DB i wszystkie obrazy są ładowane (i analizowany => powolny) i sprawdzić wtedy dzieje się „w kod". Następnie wypróbowałem Where(i => i.IsDeleted.Equals(false))
, który działał dobrze i sprawdzanie odbywało się przez SQL.
Dlaczego tak jest lub jak mogę uniknąć tego problemu, ponieważ pierwsza składnia jest mi o wiele lepsza?
Czy to może być błąd w wersji uf 6 lub czy dzieje się to w wersjach EF?
UPDATE:
Problemem jest obsada do IEnumerable<Image>
(zrobiłem Where
nie w tej samej linii w kodzie, ale zmienił go tutaj dla uproszczenia), ale używam tego również zrobić .OrderBy(...).ThenBy(...)
korzystania Func<T, TKey>
przyc i że ma powrócić IOrderedEnumerable
a nie IOrderedQueryable
...
UPDATE 2: rozwiązać za pomocą klawiszy Expression<Func<T, TKey>>
...
Hrm. To ciekawe. A co z tym, gdzie (i => i.IsDeleted == false)? – Tim
@Tim: To samo, co '! I.IsDeleted', ale myślę, że to może być moja domniemana obsada dla' IEnumerable 'a nie' Where' (zrobiłem "Equals'" inline ", ale'! '" w następnym wierszu ") - Prowadzę dochodzenie ... –
ChrFin
@chrfin OK, więc oto jest powód. Dostaniesz wszystkie elementy z bazy danych do pamięci, wykonując 'IEnumerable items = db.Images;' Zamiast tego użyj 'IQueryable', aby utworzyć zapytanie w kilku liniach i nie wykonywać go, dopóki naprawdę tego nie chcesz. –
MarcinJuraszek