2013-04-09 17 views
7

Stworzyłem projekt WebApi w VS 2012, używając NHibernate jako mojego ORM i zamierzam włączyć na nim obsługę Odata. Dlatego stworzyłem kontroler testowy z pojedynczą metodą Get, która zwraca listę elementów z tabeli w mojej bazie danych.Limitować serwery przy pomocy kontrolera WebApi i ODATA w/Nhibernate

Wszystko działa dobrze, mogę używać OData do filtrowania i porządkowania wyników itp. Problem polega na tym, że nie mogłem znaleźć sposobu na ograniczenie ilości danych zwracanych z bazy danych do kontrolera, a ta tabela ma miliony zapisów.

Użycie atrybutu Queryable tylko wydaje się ograniczać ilość danych zwracanych do klienta, ale nie ilość danych zwróconych z bazy danych.

Próbowałem przyłożenie Take(n) na IQueryable wewnątrz metody GET przed wpuszczeniem go, a to ogranicza wyniki sprowadzony z DB, ale łamie filtrowanie OData, ponieważ jeśli spróbujesz zapytać podmiot, który nie jest w pierwszych n wynikach, po prostu zwraca pustą kolekcję.

Wiem, że można użyć parametru OData, aby to osiągnąć, ale nie chciałbym polegać na dostarczaniu go przez klienta/konsumenta, aby upewnić się, że nie dostarczam niepotrzebnie tysięcy lub nawet milionów rekordów Nie zamierzam użyć.

Próbowałem również ręcznie sprawdzić, czy klient podał najwyższy parametr ciągu zapytania, zastosować transformację OData do mojego Queryable, a następnie zastosować metodę Take(n) w stosunku do przekształconego zapytania. To podejście umożliwiło mi filtrowanie dla dowolnego obiektu za pomocą OData, ale łamie ono stronicowanie, ponieważ jeśli użyję parametru $Skip=n, ponownie zwróci pustą kolekcję.

Czy istnieje sposób, aby niezawodnie ograniczyć wyniki pobrane z bazy danych, nie łamiąc obsługi OData?

+1

Co używasz jako pomostu między OData i NHibernate? Czy robisz ręcznie, przekształcając OData w NHibernate IQueryable, czy używasz biblioteki? Ponadto, w przeszłości widziałem ludzi, którzy automatycznie nałożyli TOP 1000 na wszystkie wyniki zwrócone przez interfejs API i wysłali informacje wskazujące, że otrzymali tylko część żądanych danych i często udostępniają wstępnie utworzony adres URL, który może wywołać osoba dzwoniąca. użyj, który zwróci następne 1000 wyników. Osoba dzwoniąca będzie nadal korzystać z podanych adresów URL, dopóki nie otrzyma wszystkich danych. –

+0

Nie używam OData do tworzenia zapytań bezpośrednio, ale raczej jako narzędzie wygody dla mojego klienta do filtrowania zwróconych wyników z istniejących metod. Tak na przykład mam metody GetAllProducts(), które wykonuje kwerendy przy użyciu Linq do NHibernate, i zwracam, że IQueryable. Zachowanie, które opisujesz, jest domyślnym zachowaniem przy korzystaniu z właściwości PageSize w Queryable atribute, ale jak wspomnę w moim poście, ogranicza to tylko to, co klient otrzymuje, ale nie wyniki, które są pobierane z DB do mojej metody serwisowej. – andyroschy

Odpowiedz

2

Niedawno to stwierdziliśmy. Nie stosujemy Take (pageSize), gdy włączone jest stronicowanie sterowane przez serwer, ponieważ musimy ustalić, czy link do następnej strony powinien zostać wygenerowany, czy nie. Po prostu wyliczamy zestaw wyników dla liczby stron i sprawdzamy, czy istnieje więcej elementów, czy nie. Myśleliśmy, że większość dostawców generalnie wprowadza częściowy zestaw wyników, ponieważ IQueryable jest ogólnie leniwą implementacją. Okazało się, że to nieprawda. Ponadto baza danych może zoptymalizować zapytanie, jeśli wie, że wymagana jest tylko strona o rozmiarach strony.

This to problem, który został dla niego otwarty. Dobrą wiadomością jest to, że Youssef już to naprawił :). To jest commit, który naprawił to. Więc jeśli złapiesz nocne kompilacje, powinieneś być dobry.

+0

Widziałem ten problem wczoraj, ale jeśli klikniesz link do poprawki, brakuje tej strony, co daje mi złe przeczucie. Postaram się zaktualizować i przetestować to, aby to zobaczyć. – andyroschy

+1

Wygląda na to, że codeplex nie rozumie już częściowego sha1. W każdym razie ten link powinien działać https://aspnetwebstack.codeplex.com/SourceControl/changeset/8517d73f5f60ffb3e1c8a590af4695c7bda37709 –

Powiązane problemy