2013-08-16 4 views
5

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>> ...

+1

Hrm. To ciekawe. A co z tym, gdzie (i => i.IsDeleted == false)? – Tim

+0

@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

+2

@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

Odpowiedz

0

T Problem polegał na tym, że gdy tylko użyjesz IEnumerable, zapytanie zostanie wykonane, a wszystkie następujące zapytania staną się LINQ dla zapytań o obiekty.

Mój błąd, który pozwolił na to pytanie było to, że testowany zapytań następujący sposób:

IEnumerable<Image> items = db.Images.Where(i => i.IsDeleted.Equals(false)); 

i

IEnumerable<Image> items = db.Images; 
images = images.Where(i => !i.IsDeleted); 

Tak więc w pierwszym przypadku Where nadal wykonywane przeciwko IQueryable, ale w drugim przypadku przeciwko IEnumerable.

Później pojawił się kolejny problem, że dla OrderBy i IQueryable trzeba Expression<Func<T, K>> parametry i użyłem Expression<Func<T, IComperable>>, ale np Func<T, int> nie można przesłać do Func<T, IComperable> przez Entity Framework.
Aby uzyskać szczegółowe informacje na temat sposobu rozwiązania tego problemu, zobacz inne moje pytanie: HERE

Powiązane problemy