Разбиение на страницы на стороне сервера с помощью метода ODF WCF и метода GetContinuation () - PullRequest
2 голосов
/ 24 марта 2011

Я использую метод QueryOperationResponse GetContinuation (), чтобы попытаться пролистать очень большой набор данных, считывая канал odata wcf. Я использую некоторые вспомогательные библиотеки OData, приобретенные у Microsoft.

Проблема в том, что процесс подкачки, похоже, застрял в бесконечном цикле и никогда не заканчивается. Например, если я установил размер страницы в 10000 записей, а для получения 80000 записей, я заметил, что цикл продолжается более 8 итераций, когда он должен быть завершен.

Ниже приведен класс, который запрашивает службу и реализует пейджинг (внизу). Я также заметил, что «OriginalString» NextLinkUri никогда не меняется с каждой итерацией, что я считаю неправильным? Надеюсь, я просто упускаю что-то действительно очевидное, я думаю, что это правильный путь к странице:

    private static IList<dynamic> Get(string serviceUri, NameValueCollection queryOptions, IAuthenticationScheme authenticationScheme)
    {
        string baseUri;
        string entitySet;
        string entityKey;
        string queryString;
        ValidateServiceUri(serviceUri, out baseUri, out entitySet, out entityKey, out queryString);
        string resource = !string.IsNullOrEmpty(entityKey) ? entitySet + "(" + entityKey + ")" : entitySet;

        DataServiceContext context = new DataServiceContext(new Uri(baseUri));
        context.IgnoreMissingProperties = true;

        DataServiceContextHandler handler = new DataServiceContextHandler(authenticationScheme);
        handler.HandleGet(context);

        DataServiceQuery<EntryProxyObject> query = context.CreateQuery<EntryProxyObject>(resource);

        NameValueCollection options = HttpUtility.ParseQueryString(queryString);
        options.Add(queryOptions);

        foreach (string key in options.AllKeys)
        {
            query = query.AddQueryOption(key, options[key]);
        }

        QueryOperationResponse<EntryProxyObject> response = query.Execute() as QueryOperationResponse<EntryProxyObject>;

        IList<dynamic> result;
        if (options["$inlinecount"] == "allpages")
        {
            result = new DynamicEntityCollection(response.TotalCount) as IList<dynamic>;
        }
        else
        {
            result = new List<dynamic>();
        }

        foreach (EntryProxyObject proxy in response)
        {
            DynamicEntity entity = new DynamicEntity(proxy.Properties);
            result.Add(entity);
        }

        while (response.GetContinuation() != null)
        {
            DataServiceQueryContinuation<EntryProxyObject> continuation = response.GetContinuation();
            QueryOperationResponse<EntryProxyObject> nextResponse = context.Execute<EntryProxyObject>(continuation);

            Console.WriteLine("Uri: " + continuation.NextLinkUri.OriginalString); 

            foreach (EntryProxyObject proxy in nextResponse)
            {
                DynamicEntity entity = new DynamicEntity(proxy.Properties);
                result.Add(entity);
            }
        }

        return result;
    }

Вот как я называю метод:

return OData.Get("http://xxx.x.xxx.xx/MyDataService.svc/MyProducts", "$filter=Index gt 0");

1 Ответ

4 голосов
/ 25 марта 2011

Вы всегда смотрите на продолжение первого ответа. Это остается постоянным (по очевидным причинам). Вам нужно взглянуть на продолжение nextResponse в вашем коде, чтобы выяснить, есть ли еще данные для чтения, и получить продолжение для перехода на следующую страницу. Приведенный выше код читает первую страницу, а затем снова и снова читает вторую страницу.

...