2009-09-25 14 views
9

Mamy usługę WCF, która jest używana do wysyłania zapytań do baz danych danych (teraz SQL Server 2005). Ta usługa może zwracać raczej duże ilości danych; 60000+ wystąpień naszej klasy encji, która zawiera ~ 20 właściwości. Właściwości są w większości prymitywami, takimi jak string, int, DateTime z parą wskazującą na inne podmioty, które mogą z kolei wskazywać na inne; te hierarchie nie są jednak zbyt głębokie.Najlepsza praktyka dla usługi WCF z dużą ilością danych?

Jedna aplikacja zużywająca tę usługę zwykle tworzy zapytania zwracające tylko uzasadnioną liczbę jednostek (od kilku do kilku tysięcy). Czasami jednak tworzy zapytanie, które zwróci dużą ilość, jak podano powyżej (i będzie musiało przetworzyć dane, więc zawężenie kryteriów zapytania nie jest opcją).

To, co chcemy zrobić, to wprowadzić funkcję "stronicowania", w której klient może wywołać usługę i odzyskać określoną liczbę instancji, a następnie zadzwonić ponownie i uzyskać następny fragment, aż do pełny wynik jest pobierany. Nie pracując strasznie dużo z WCF, nie jestem pewien co do najlepszego sposobu osiągnięcia tego.

Jedną z rzeczy, o których należy pamiętać, jest to, że podstawowe dane mogą bardzo dobrze ulec zmianie podczas pobierania porcji. Nie jestem do końca pewien, czy jest to dla nas problem, czy nie (trzeba to trochę zająć), ale może tak być, więc mile widziany jest również wkład w obsługę tej konkretnej sytuacji.

Rozpoczęliśmy analizę przesyłania strumieniowego odpowiedzi, ale chcielibyśmy również zobaczyć próbki stronicowania, ponieważ możemy chcieć rozpocząć przetwarzanie danych przed uzyskaniem pełnego wyniku.

Krótko mówiąc, czy istnieje najlepsza praktyka w tego rodzaju scenariuszu (lub jakiekolwiek absolutne nie-nie, o czym powinniśmy być świadomi)?

+1

Fredrik - czy widziałeś to - http://stackoverflow.com/questions/741413/implementing-pager-through-wcf-service- nieco podstawowy chociaż – RichardOD

+0

@RichardOD: dzięki za link. Myślę, że musimy zaatakować to na niższym poziomie, ale dam mu trochę czasu na eksperymenty. –

Odpowiedz

9

Używanie konfiguracji powiązania przesyłania strumieniowego na kliencie i serwerze z MessageContract posiadającym tylko Stream [MessageBodyMember] (i dowolne inne metadane wysłane jako [MessageHeader]) pozwoli ci wykonać całą pracę w jednym wywołaniu bez obawy o stronicowanie (po prostu użyj modułu wyliczającego po stronie serwera, aby zasilić strumień i przetworzyć pojedyncze elementy, tak jak pojawiają się one na kliencie), ale musisz rzucić własne kadrowanie w strumieniu (np. serializować/deserializować elementy ręcznie w strumieniu za pomocą DataContractSerializer lub cokolwiek). Zrobiłem to i działa świetnie, ale to trochę cierpienie.

Jeśli chcesz wykonać stronicowanie, prostym sposobem jest użycie sesyjnego kanału WCF w połączeniu z transakcją migawki (jeśli używasz programu SQL Server lub czegoś, co obsługuje je jako źródło encji). Uruchom migawkę tx przy pierwszym żądaniu, a następnie przywiąż tryb tx do sesji, aby sprawdzić stabilny obraz danych między żądaniami stron - tx zostanie zwolniony po zamknięciu sesji (lub czasie out, jeśli klient rozłączył się nieoczekiwanie). Następnie klient żąda ostatniej kluczowej wartości, jaką zobaczył + ile żądanych rekordów (uwaga na maxReceivedMessageSize - pozostawia dużo miejsca nad głową). Ponieważ jesteś w migawce, nie musisz się martwić o zmiany - zobaczysz spójny widok na czas trwania zrzutu. Jeśli nie możesz zarchiwizować danych źródłowych, aby zapobiec ich zmianie w trakcie pobierania, życie jest o wiele trudniejsze. Zawsze wykonalne, ale projektowanie jest bardzo specyficzne dla danych.

+0

Dzięki za twój wkład. Zajrzę do pomysłu na migawkę. Wygląda na to, że niektóre usługi mogą zostać przeniesione do Linq-sql w celu obsługi stronicowania. Sprawdzę, czy można połączyć te pomysły, co byłoby idealne. –

+0

Mogą używać LINQ do SQL dla wszystkiego.Jedyną sztuczką z migawką jest to, że musisz dotknąć wszystkich rekordów (i powiązanych danych) raz na początku (ale nie zwracaj ich do klienta), aby włączyć go do migawki. Dyskretne polecenie SQL byłoby prawdopodobnie lepsze. – nitzmahone

Powiązane problemy