OData 服务未返回完整响应

发布于 2024-11-15 17:48:17 字数 1571 浏览 2 评论 0原文

我正在使用 Odata RESTful 服务阅读 Sharepoint 列表数据(>20000 个条目),详细信息请参见此处 -http://blogs.msdn.com/b/ericwhite/archive/2010/12/09/getting-started-using-the- odata-rest-api-to-query-a-sharepoint-list.aspx

我能够读取数据,但只获取前 1000 条记录。我还检查了 sharepoint 服务器上的列表视图限制是否设置为 5000。请指教。

更新:

@Turker:你的答案很正确!非常感谢。我在第一次迭代中获得了前 2000 条记录。但是,我在 while 循环的每次迭代中都得到相同的记录。我的代码如下-

                         ...initial code...
                     int skipCount =0;
  while (((QueryOperationResponse)query).GetContinuation() != null)
                {
                    //query for the next partial set of customers
                    query = dc.Execute<CATrackingItem>(
                        ((QueryOperationResponse)query).GetContinuation().NextLinkUri
                        );

                    //Add the next set of customers to the full list
                    caList.AddRange(query.ToList());

                    var results = from d in caList.Skip(skipCount)
                                  select new
                                  {
                                      Actionable = Actionable,
                                    };  Created = d.Created,

                        foreach (var res in results)
                        {

                            structListColumns.Actionable = res.Actionable;
                            structListColumns.Created= res.Created;
                        }
                         skipCount = caList.Count;
                     }//Close of while loop

I am reading Sharepoint list data (>20000 entries) using Odata RESTful service as detailed here -http://blogs.msdn.com/b/ericwhite/archive/2010/12/09/getting-started-using-the-odata-rest-api-to-query-a-sharepoint-list.aspx

I am able to read data but I get only the first 1000 records. I also checked that List View Throttling is set to 5000 on sharepoint server. Kindly advise.

Update:

@Turker: Your answer is spot on!! Thank you very much. I was able to get the first 2000 records in first iteration. However, I am getting the same records in each iteration of while loop. My code is as follows-

                         ...initial code...
                     int skipCount =0;
  while (((QueryOperationResponse)query).GetContinuation() != null)
                {
                    //query for the next partial set of customers
                    query = dc.Execute<CATrackingItem>(
                        ((QueryOperationResponse)query).GetContinuation().NextLinkUri
                        );

                    //Add the next set of customers to the full list
                    caList.AddRange(query.ToList());

                    var results = from d in caList.Skip(skipCount)
                                  select new
                                  {
                                      Actionable = Actionable,
                                    };  Created = d.Created,

                        foreach (var res in results)
                        {

                            structListColumns.Actionable = res.Actionable;
                            structListColumns.Created= res.Created;
                        }
                         skipCount = caList.Count;
                     }//Close of while loop

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

淡墨 2024-11-22 17:48:17

您是否在 Feed 末尾看到 元素?

例如,如果您查看

http://services.odata.org/Northwind/Northwind .svc/Customers/

看到

<link rel="next" href="http://services.odata.org/Northwind/Northwind.svc/Customers/?$skiptoken='ERNSH'" />

您将在提要末尾

http://services.odata.org/Northwind/Northwind.svc/Customers/?$skiptoken='ERNSH' 

,这意味着该服务正在实现服务器端分页,您需要发送查询才能获取下一组结果。

Do you see a <link rel="next"> element at the end of the feed?

For example, if you look at

http://services.odata.org/Northwind/Northwind.svc/Customers/

you will see

<link rel="next" href="http://services.odata.org/Northwind/Northwind.svc/Customers/?$skiptoken='ERNSH'" />

at the end of the feed which means the service is implementing server side paging and you need to send the

http://services.odata.org/Northwind/Northwind.svc/Customers/?$skiptoken='ERNSH' 

query to get the next set of results.

血之狂魔 2024-11-22 17:48:17

我没有发现你的代码有什么特别的错误。您可以尝试转储请求的 URL(从代码中或使用 fiddler 之类的东西)以查看客户端是否确实发送相同的查询(从而获得相同的响应)。

无论如何,这里是一个可以工作的示例代码(使用示例服务):

DataServiceContext ctx = new DataServiceContext(new Uri("http://services.odata.org/Northwind/Northwind.svc"));

QueryOperationResponse<Customer> response = (QueryOperationResponse<Customer>)ctx.CreateQuery<Customer>("Customers").Execute();
do
{
    foreach (Customer c in response)
    {
        Console.WriteLine(c.CustomerID);
    }

    DataServiceQueryContinuation<Customer> continuation = response.GetContinuation();
    if (continuation != null)
    {
        response = ctx.Execute(continuation);
    }
    else
    {
        response = null;
    }
} while (response != null);

I don't see anything particularly wrong with your code. You can try to dump the URLs beign requested (either from the code, or using something like fiddler) to see if the client really sends the same queries (and thus getting same responses).

In any case, here is a sample code which does work (using the sample service):

DataServiceContext ctx = new DataServiceContext(new Uri("http://services.odata.org/Northwind/Northwind.svc"));

QueryOperationResponse<Customer> response = (QueryOperationResponse<Customer>)ctx.CreateQuery<Customer>("Customers").Execute();
do
{
    foreach (Customer c in response)
    {
        Console.WriteLine(c.CustomerID);
    }

    DataServiceQueryContinuation<Customer> continuation = response.GetContinuation();
    if (continuation != null)
    {
        response = ctx.Execute(continuation);
    }
    else
    {
        response = null;
    }
} while (response != null);
大海や 2024-11-22 17:48:17

我遇到了同样的问题,并希望它成为一个通用的解决方案。
因此,我使用 GetAlltems 方法扩展了 DataServiceContext。

    public static List<T> GetAlltems<T>(this DataServiceContext context)
    {
        return context.GetAlltems<T>(null);
    }

    public static List<T> GetAlltems<T>(this DataServiceContext context, IQueryable<T> queryable)
    {
        List<T> allItems = new List<T>();
        DataServiceQueryContinuation<T> token = null;

        EntitySetAttribute attr = (EntitySetAttribute)typeof(T).GetCustomAttributes(typeof(EntitySetAttribute), false).First();

        // Execute the query for all customers and get the response object.
        DataServiceQuery<T> query = null;

        if (queryable == null)
        {
            query = context.CreateQuery<T>(attr.EntitySet);
        }
        else
        {
            query = (DataServiceQuery<T>) queryable;
        }

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

        // With a paged response from the service, use a do...while loop 
        // to enumerate the results before getting the next link.
        do
        {
            // If nextLink is not null, then there is a new page to load.
            if (token != null)
            {
                // Load the new page from the next link URI.
                response = context.Execute<T>(token);
            }

            allItems.AddRange(response);
        }
        // Get the next link, and continue while there is a next link.
        while ((token = response.GetContinuation()) != null);

        return allItems;
    }

I had the same problem, and wanted it to be a generic solution.
So I've extended DataServiceContext with a GetAlltems methode.

    public static List<T> GetAlltems<T>(this DataServiceContext context)
    {
        return context.GetAlltems<T>(null);
    }

    public static List<T> GetAlltems<T>(this DataServiceContext context, IQueryable<T> queryable)
    {
        List<T> allItems = new List<T>();
        DataServiceQueryContinuation<T> token = null;

        EntitySetAttribute attr = (EntitySetAttribute)typeof(T).GetCustomAttributes(typeof(EntitySetAttribute), false).First();

        // Execute the query for all customers and get the response object.
        DataServiceQuery<T> query = null;

        if (queryable == null)
        {
            query = context.CreateQuery<T>(attr.EntitySet);
        }
        else
        {
            query = (DataServiceQuery<T>) queryable;
        }

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

        // With a paged response from the service, use a do...while loop 
        // to enumerate the results before getting the next link.
        do
        {
            // If nextLink is not null, then there is a new page to load.
            if (token != null)
            {
                // Load the new page from the next link URI.
                response = context.Execute<T>(token);
            }

            allItems.AddRange(response);
        }
        // Get the next link, and continue while there is a next link.
        while ((token = response.GetContinuation()) != null);

        return allItems;
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文