SharePoint Foundation 2010 托管客户端对象模型概述(九) --访问大型列表

SharePoint 开发指南指示,您不应尝试在单个查询中检索 2000 个以上的项目。如果您的应用程序中可能会出现这种情况,可以考虑在 CAML 查询中使用 RowLimit 元素,以限制客户端对象模型可以为应用程序检索的数据量。有时您必须访问可能包含 2000 个以上项目的列表中的所有项目。如果必须如此,则最好进行分页,一次查看 2000 个项目。本节介绍了使用 ListItemCollectionPosition 属性进行分页的方法。



C#

using System;

using System.Linq;

using Microsoft.SharePoint.Client;



class Program

{

    static void Main()

    {

        ClientContext clientContext =

            new ClientContext("http://intranet.contoso.com");



        List list = clientContext.Web.Lists

            .GetByTitle("Client API Test List");



        // First, add 20 items to Client API Test List so that there are

        // enough records to show paging.

        ListItemCreationInformation itemCreateInfo =

            new ListItemCreationInformation();

        for (int i = 0; i < 20; i++)

        {

            ListItem listItem = list.AddItem(itemCreateInfo);

            listItem["Title"] = String.Format("New Item #{0}", i);

            listItem["Category"] = "Development";

            listItem["Estimate"] = i;

            listItem.Update();

        }

        clientContext.ExecuteQuery();



        // This example shows paging through the list ten items at a time.

        // In a real-world scenario, you would want to limit a page to

        // 2000 items.

        ListItemCollectionPosition itemPosition = null;

        while (true)

        {

            CamlQuery camlQuery = new CamlQuery();

            camlQuery.ListItemCollectionPosition = itemPosition;

            camlQuery.ViewXml =

                @"<View>

                    <ViewFields>

                      <FieldRef Name='Title'/>

                      <FieldRef Name='Category'/>

                      <FieldRef Name='Estimate'/>

                    </ViewFields>

                    <RowLimit>10</RowLimit>

                  </View>";

            ListItemCollection listItems = list.GetItems(camlQuery);

            clientContext.Load(listItems);

            clientContext.ExecuteQuery();

            itemPosition = listItems.ListItemCollectionPosition;

            foreach (ListItem listItem in listItems)

                Console.WriteLine("  Item Title: {0}", listItem["Title"]);

            if (itemPosition == null)

                break;

            Console.WriteLine(itemPosition.PagingInfo);

            Console.WriteLine();

        }

    }

}

该示例将生成以下输出:



  Item Title: Write specs for user interface.

  Item Title: Develop proof-of-concept.

  Item Title: Write test plan for user interface.

  Item Title: Validate SharePoint interaction.

  Item Title: Develop user interface.

  Item Title: New Item #0

  Item Title: New Item #1

  Item Title: New Item #2

  Item Title: New Item #3

  Item Title: New Item #4

Paged=TRUE&p_ID=10



  Item Title: New Item #5

  Item Title: New Item #6

  Item Title: New Item #7

  Item Title: New Item #8

  Item Title: New Item #9

  Item Title: New Item #10

  Item Title: New Item #11

  Item Title: New Item #12

  Item Title: New Item #13

  Item Title: New Item #14

Paged=TRUE&p_ID=20



  Item Title: New Item #15

  Item Title: New Item #16

  Item Title: New Item #17

  Item Title: New Item #18

  Item Title: New Item #19



异步处理

如果您要构建必须附加到可能不可用的 SharePoint 网站的应用程序,或者您必须定期调用可能要花很长时间的查询,则应考虑使用异步处理。这样,当查询在单独的线程中执行时,您的应用程序能够继续响应用户。在主线程中,您可以设置一个计时器。如果查询所花时间长于所需阈值,该计时器可通知您,以便您可以告诉用户查询状态,并在查询最终完成时显示结果。



客户端对象模型的 JavaScript 版本和 Silverlight 版本(在修改用户界面时)都使用异步处理。SharePoint 2010 SDK 中的主题Data Retrieval Overview包含有关如何通过 JavaScript 和 Silverlight 使用异步处理的示例。



在构建基于 .NET Framework 的传统应用程序(如 Windows 窗体或 WPF 应用程序)时,可能需要使用异步处理。以下示例使用 BeginInvoke 方法异步执行查询。请注意,该代码会将一个语句式 lambda 表达式传递给 BeginInvoke 方法,这样便可方便地创建此模式,因为语句式 lambda 表达式可以引用该表达式所在方法中的自动变量。您可以看到语句式 lambda 表达式可以访问 clientContext 变量和 newListCollection 变量。Microsoft Visual C# 闭包使该语言能够按您预期的方式工作。



C#

using System;

using System.Collections.Generic;

using Microsoft.SharePoint.Client;



class Program

{

    static void Main(string[] args)

    {

        AsynchronousAccess asynchronousAccess = new AsynchronousAccess();

        asynchronousAccess.Run();

        Console.WriteLine("Before exiting Main");

        Console.WriteLine();

        Console.WriteLine("In a real application, the application can");

        Console.WriteLine("continue to be responsive to the user.");

        Console.WriteLine();

        Console.ReadKey();

    }

}



class AsynchronousAccess

{

    delegate void AsynchronousDelegate();



    public void Run()

    {

        Console.WriteLine("About to start a query that will take a long time.");

        Console.WriteLine();

        ClientContext clientContext =

            new ClientContext("http://intranet.contoso.com");

        ListCollection lists = clientContext.Web.Lists;

        IEnumerable<List> newListCollection = clientContext.LoadQuery(

            lists.Include(

                list => list.Title));

        AsynchronousDelegate executeQueryAsynchronously =

            new AsynchronousDelegate(clientContext.ExecuteQuery);

        executeQueryAsynchronously.BeginInvoke(

            arg =>

            {

                clientContext.ExecuteQuery();

                Console.WriteLine("Long running query completed.");

                foreach (List list in newListCollection)

                    Console.WriteLine("Title: {0}", list.Title);

            }, null);

    }

}

该示例将生成以下输出。



About to start a query that will take a long time.



Before exiting Main



In a real application, the application can

continue to be responsive to the user.



Long running query completed.

Title: Announcements

Title: Cache Profiles

Title: Calendar

Title: Client API Test List

Title: Content and Structure Reports

Title: Content type publishing error log

Title: Converted Forms

Title: Customized Reports

Title: Eric's ToDo List

Title: Eric's Wiki

Title: Form Templates

Title: Links

你可能感兴趣的:(SharePoint)