Condividi tramite


Data Retrieval Overview

Applies to: SharePoint Foundation 2010

Available in SharePoint Online

You can use the new client object model to retrieve properties for a specific SharePoint client object (ClientObject, or in ECMAScript (JavaScript, JScript), ClientObject), to retrieve child objects and their associated properties, or to retrieve child items in a collection. The object model uses explicit data-retrieval semantics that you must follow to retrieve functioning data. The client object models do not persist data that is retrieved locally on the client.

Performing data retrieval involves the following procedure:

  1. Return the context for a client request by using the ClientContext() constructor (JavaScript: ClientContext(serverRelativeUrl)).

  2. Use the object model to specify an object to retrieve or from which to retrieve data.

  3. Load the object or collection, through either an in-place load that uses the Load<T>(T, []) (JavaScript: load(clientObject)) method to return a specific object, collection, or data, or through a queryable load that uses the LoadQuery() (JavaScript: loadQuery(clientObjectCollection, exp)) method to return an enumerable collection of objects.

  4. Execute the query by calling the synchronous ExecuteQuery() method in the .NET managed version of the client object model, or when, in the Silverlight version, code executes from threads that do not modify the user interface (UI). In the JavaScript version of the object model, or when the Silverlight version modifies the UI, data-retrieval uses an asynchronous callback model and you must call the ExecuteQueryAsync(ClientRequestSucceededEventHandler, ClientRequestFailedEventHandler) method (JavaScript: executeQueryAsync(succeededCallback, failedCallback)), which includes parameters for methods to handle success or failure of the request. When the method call to execute the query returns (either synchronously or asynchronously), you can access the results of the query on the object from which you initiated the query.

Query syntax versus method syntax

Both forms of Language-Integrated Query (LINQ) syntax--query syntax and method syntax--can be used in the managed client object model to load individual objects, specific object properties, or enumerable object collections.

Note

Two points to keep in mind when using LINQ to query against the client object model:

  • When you use LINQ to create queries against the client object model, you are using LINQ to Objects, not the LINQ to SharePoint provider, which can only be used when you write code against the server object model.

  • When your query is designed to return a subset of list items from a list, it is more efficient to use a CAML query than a LINQ query. This is because all the list items are sent from the content database to the front-end web server and loaded into memory. Only then is the LINQ filter is applied. With a CAML query, the filtering is done on the database server. This point applies only to queries that filter the items on a list. Other kinds of LINQ queries, such as returning a subset of the lists from a web site, are more efficient.

Query syntax can only be used in the LoadQuery() method and requires two steps--defining the query expression, and retrieving the result of the query. This process is illustrated in the following code example, which returns all lists from the current Web site that have a defined title.

var query = from list 
    in clientContext.Web.Lists
    where list.Title != null
    select list;

var result = clientContext.LoadQuery(query);
clientContext.ExecuteQuery();
Dim query = From list In clientContext.Web.Lists _ 
    Where list.Title IsNot Nothing _ 
    Select list

Dim result = clientContext.LoadQuery(query)
clientContext.ExecuteQuery()

Method syntax can be used with either the Load<T>(T, []) or LoadQuery() method and uses lambda expressions. The following example uses method syntax to define the same query for lists that have a title.

clientContext.Load(clientContext.Web, 
    website => website.Lists.Include(
        list => list.Title).Where(
            list => list.Title != null));

clientContext.ExecuteQuery();
clientContext.Load(clientContext.Web, _
    Function(website) website.Lists.Include( _
    Function(list) list.Title).Where( _
    Function(list) list.Title IsNot Nothing))

    clientContext.ExecuteQuery()

The previous example illustrates how to use the Include<TSource>(IQueryable<TSource>, []) method to limit what properties are returned from a collection of objects, which improves performance. The query returns only the titles of lists that have a title.

The next example uses query syntax to retrieve filterable fields of a list that are not hidden.

FieldCollection collField = oList.Fields;

var query = from field
        in collField
        where field.Hidden == false
        && field.Filterable == true
        select field;

var result = clientContext.LoadQuery(query);

clientContext.ExecuteQuery();
Dim collField As FieldCollection = oList.Fields

Dim query = From field In collField _ 
    Where field.Hidden = False AndAlso field.Filterable = True _ 
    Select field

Dim result = clientContext.LoadQuery(query)

clientContext.ExecuteQuery()

The following example performs the same query as the previous one, but instead, uses method syntax in the Load<T>(T, []) method.

clientContext.Load(oList,
    list => list.Fields.Where(
    field => field.Hidden == false
        && field.Filterable == true));

    clientContext.ExecuteQuery();
clientContext.Load(oList, Function(list) list.Fields.Where( _
    Function(field) field.Hidden = False _
    AndAlso field.Filterable = True))

    clientContext.ExecuteQuery()

Using query strings in ECMAScript

The JavaScript methods for retrieving objects and data do not accept LINQ syntax, but you can use a string expression to define a basic query. The following example uses the load(clientObject) method to retrieve only the title and ID of a specific list.

clientContext.load(oList, 'Title' ,'Id');

clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));

When working with a list collection, specify Include to return only the title and ID of each list, as seen in the following example.

clientContext.load(collList, 'Include(Title, Id)');

Alternatively, you can use fields of the *PropertyNames class that is associated with the object or collection to specify which properties to return, as seen in the following example:

var propTitle = SP.ListPropertyNames.title;
var propId = SP.ListPropertyNames.id;
clientContext.load(collList, 'Include(' + propTitle + ', ' + propId + ')');

You can also nest the Include keyword within the query string that you pass. The following example uses the loadQuery(clientObjectCollection, exp) method to retrieve the titles of all lists, as well as the titles and descriptions of all fields in all the lists.

myListArray = clientContext.loadQuery(collList, 
    'Include(Title,Fields.Include(Title,Description))');

In-place load versus queryable load

There are two ways to use LINQ-based queries with the client object model: through an in-place load and through a queryable load. A queryable load returns data in another result array, while an in-place load returns data in the object itself.

An in-place load makes a request to load objects and their data and maintains object identity through multiple requests. You perform in-place loads through the Load<T>(T, []) method of a client context. The following example loads all the lists of the current Web site as well as all their default properties. After query execution, code has access to the entire list collection and the default list properties:

clientContext.Load(clientContext.Web.Lists); 
clientContext.ExecuteQuery();

In a queryable load, the query is separate from the returned results. Unlike an in-place load, in a queryable load object identity is not retained, so your code must itself maintain the objects that are returned. The following example uses query syntax to return all the lists of the Web site.

var query = from list 
    in clientContext.Web.Lists 
    select list;

var result = clientContext.LoadQuery(query);

clientContext.ExecuteQuery();
Dim query = From list In clientContext.Web.Lists _ 
    Select list

Dim result = clientContext.LoadQuery(query)

clientContext.ExecuteQuery()

This example fills result with an IEnumerable<T> interface of List objects your code can work with and must maintain on its own. Note that context.Web.Lists remains empty and still returns a count of 0; to get the list count, you must use Count() of your IEnumerable<T> interface.

How to retrieve objects

The following example shows how to load an object to access its properties. Because the list object is loaded in place, all default properties of the list can be accessed.

ClientContext clientContext =  new ClientContext("http://MyServer/sites/MySiteCollection");
Web oWebsite = clientContext.Web;
ListCollection collList = oWebsite.Lists;

List oList = collList.GetByTitle("Announcements");

clientContext.Load(oList);

clientContext.ExecuteQuery();

Console.WriteLine("Title: {0} Created: {1}", oList.Title, oList.Created);
Dim clientContext As New ClientContext("http://MyServer/sites/MySiteCollection")
Dim oWebsite As Web = clientContext.Web
Dim collList As ListCollection = oWebsite.Lists

Dim oList As List = collList.GetByTitle("Announcements")

clientContext.Load(oList)

clientContext.ExecuteQuery()

Console.WriteLine("Title: {0} Created: {1}", oList.Title, oList.Created)
function retrieveWebSite() {
    var clientContext = new SP.ClientContext('/sites/MySiteCollection');
    var oWebsite = clientContext.get_web();
    var collList = oWebsite.get_lists();

    this.oList = collList.getByTitle('Announcements');
    clientContext.load(oList);

    clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}

function onQuerySucceeded(sender, args) {
    alert('Title: ' + oList.get_title() + ' Created: ' + oList.get_created());
}

function onQueryFailed(sender, args) {
    alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

Some properties are not available by default when you retrieve certain objects, and to access these properties you must explicitly load the properties. The previous example loads a specific list object and can access both properties because they are available by default on the object. However, if the example tries to access properties that are not available by default, such as OnQuickLaunch (JavaScript: onQuickLaunch), a PropertyOrFieldNotInitializedException is returned. The following table lists properties that are not available by default when you retrieve the object.

Object

Properties

Folder

ContentTypeOrder (JavaScript: contentTypeOrder), UniqueContentTypeOrder (JavaScript: uniqueContentTypeOrder)

List

BrowserFileHandling (JavaScript: browserFileHandling), DataSource (JavaScript: dataSource), EffectiveBasePermissions (JavaScript: effectiveBasePermissions), HasUniqueRoleAssignments (JavaScript: hasUniqueRoleAssignments), IsSiteAssetsLibrary (JavaScript: isSiteAssetsLibrary), OnQuickLaunch (JavaScript: onQuickLaunch), RoleAssignments (JavaScript: roleAssignments), SchemaXml (JavaScript: schemaXml), ValidationFormula (JavaScript: validationFormula), ValidationMessage (JavaScript: validationMessage)

ListItem

DisplayName (JavaScript: displayName), EffectiveBasePermissions (JavaScript: effectiveBasePermissions), HasUniqueRoleAssignments (JavaScript: hasUniqueRoleAssignments), RoleAssignments (JavaScript: roleAssignments)

SecurableObject

HasUniqueRoleAssignments (JavaScript: hasUniqueRoleAssignments), RoleAssignments (JavaScript: roleAssignments)

Site

Usage (JavaScript: usage)

Web

EffectiveBasePermissions (JavaScript: effectiveBasePermissions), HasUniqueRoleAssignments (JavaScript: hasUniqueRoleAssignments), RoleAssignments (JavaScript: roleAssignments)

In addition to the properties listed in the previous table, parent or child objects that can be accessed through the properties of an object are not available by default. Consequently, adding oList.Items.Count in the previous example always displays 0 at the console, instead of the actual number of items if there are any, because the list item collection is not specifically requested in the Load<T>(T, []) method (JavaScript: load(clientObject)).

To access properties that are not available by default when you return an object, you must explicitly request properties. The following revision of the previous Load<T>(T, []) (JavaScript: load(clientObject)) method call makes OnQuickLaunch (JavaScript: onQuickLaunch) available.

clientContext.Load(oList,
    list => list.Title,
    list => list.Created,
    list => list.OnQuickLaunch);
clientContext.Load(oList, _
    Function(list) list.Title, _
    Function(list) list.Created, _
    Function(list) list.OnQuickLaunch)
clientContext.load(oList, 'Title', 'Created', 'OnQuickLaunch');

In the managed or Silverlight object model, if you are working with a collection of objects, use the IncludeWithDefaultProperties<TSource>(IQueryable<TSource>, []) method to include properties that are not available by default on each list that is loaded.

Note

The JavaScript object model does not have the equivalent of an IncludeWithDefaultProperties<TSource>(IQueryable<TSource>, []) method.

The following example displays the same information as the previous example for every list in the Web site.

ClientContext clientContext =  new ClientContext("http://MyServer/sites/MySiteCollection");
Web oWebsite = clientContext.Web;
ListCollection collList = oWebsite.Lists;

clientContext.Load(collList,
    lists => lists.IncludeWithDefaultProperties(
        list => list.OnQuickLaunch));

clientContext.ExecuteQuery();

foreach (List oList in collList)
{
    Console.WriteLine("Title: {0} Created: {1} QuickLaunch: {2}", oList.Title, oList.Created, oList.OnQuickLaunch);
}
Dim clientContext As New ClientContext("http://MyServer/sites/MySiteCollection")
Dim oWebsite As Web = clientContext.Web
Dim collList As ListCollection = oWebsite.Lists

clientContext.Load(collList, _
    Function(lists) lists.IncludeWithDefaultProperties( _
        Function(list) list.OnQuickLaunch))

clientContext.ExecuteQuery()

Dim oList As List
For Each oList In collList
    Console.WriteLine("Title: {0} Created: {1} QuickLaunch: {2}", oList.Title, oList.Created, oList.OnQuickLaunch)
Next oList

How to update objects

To modify an object through the client object model works similarly to modifying an object through the server object model. In both cases, you must call an Update method. However, with the client object model, changes do not take effect until the object is loaded and ExecuteQuery() or ExecuteQueryAsync(ClientRequestSucceededEventHandler, ClientRequestFailedEventHandler) (JavaScript: executeQueryAsync(succeededCallback, failedCallback)) is called. The following example changes the description of the list that is loaded.

ClientContext clientContext =  new ClientContext("http://MyServer/sites/MySiteCollection");
Web oWebsite = clientContext.Web;
ListCollection collList = oWebsite.Lists;

List oList = collList.GetByTitle("My List");

oList.Description = "Changed description...";

oList.Update();

clientContext.ExecuteQuery();
Dim clientContext As New ClientContext("http://MyServer/sites/MySiteCollection")
Dim oWebsite As Web = clientContext.Web
Dim collList As ListCollection = oWebsite.Lists

Dim oList As List = collList.GetByTitle("My List")

oList.Description = "Changed description..."

oList.Update()

clientContext.ExecuteQuery()
function updateList() {
    var clientContext = new SP.ClientContext('/sites/MySiteCollection');
    var oWebsite = clientContext.get_web();
    var collList = oWebsite.get_lists();

    this.oList = collList.getByTitle('My List');

    oList.set_title('Changed description...');

    oList.update();

    clientContext.load(oList);

    clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}

function onQuerySucceeded() {
    alert(oList.get_title() + ' created.');
}

function onQueryFailed(sender, args) {
    alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

Notice that in the previous example, modifying an object does not require loading the object on the client.

How to retrieve list items

To retrieve numerous list items, it's most efficient to use a query in Collaborative Application Markup Language (CAML) to specify which items to return. Use the CamlQuery class (JavaScript: CamlQuery) to define the query, and pass the query to the GetItems(CamlQuery) method (JavaScript: getItems(query)).

The following example uses the CamlQuery class (JavaScript: CamlQuery) to return the first 50 items in a list whose ID is less than 100. The Load<T>(T, []) method specifies IncludeWithDefaultProperties<TSource>(IQueryable<TSource>, []) to include retrieval of DisplayName.

ClientContext clientContext =  new ClientContext("http://MyServer/sites/MySiteCollection");
Web oWebsite = clientContext.Web;
ListCollection collList = oWebsite.Lists;

List oList = collList.GetByTitle("My List");

CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = "<View><Query><Where><Leq>" +
    "<FieldRef Name='ID'/><Value Type='Number'>100</Value>" +
    "</Leq></Where></Query><RowLimit>50</RowLimit></View>";

ListItemCollection collListItem = oList.GetItems(camlQuery);

clientContext.Load(collListItem,
    items => items.IncludeWithDefaultProperties(
    item=>item.DisplayName));

clientContext.ExecuteQuery();

foreach (ListItem oListItem in collListItem)
{
    Console.WriteLine("ID: {0} Display name: {1}", oListItem.Id, oListItem.DisplayName);
}
Dim clientContext As New ClientContext("http://MyServer/sites/MySiteCollection")
Dim oWebsite As Web = clientContext.Web
Dim collList As ListCollection = oWebsite.Lists

Dim oList As List = collList.GetByTitle("My List")

Dim camlQuery As New CamlQuery()
camlQuery.ViewXml = "<View><Query><Where><Leq>" + _
    "<FieldRef Name='ID'/><Value Type='Number'>100</Value>" + _
    "</Leq></Where></Query><RowLimit>50</RowLimit></View>"

Dim collListItem As ListItemCollection = oList.GetItems(camlQuery)

clientContext.Load(collListItem, _
    Function(items) items.IncludeWithDefaultProperties( _
        Function(item) item.DisplayName))

clientContext.ExecuteQuery()

Dim oListItem As ListItem
For Each oListItem In collListItem
    Console.WriteLine("ID: {0} Display name: {1}", oListItem.Id, oListItem.DisplayName)
Next oItem

Because the JavaScript object model does not have an IncludeWithDefaultProperties<TSource>(IQueryable<TSource>, []) method, the following example uses Include with the load(clientObject) method to specify retrieving the ID and display name of each list item.

function retrieveListItems() {

    var clientContext = new SP.ClientContext('/sites/MySiteCollection');
    var oList = clientContext.get_web().get_lists().getByTitle('My List');
        
    var camlQuery = new SP.CamlQuery();
    camlQuery.set_viewXml('<View><Query><Where><Leq>' + 
        '<FieldRef Name=\'ID\'/><Value Type=\'Number\'>100</Value>' + 
        '</Leq></Where></Query><RowLimit>50</RowLimit></View>');

    this.collListItem = oList.getItems(camlQuery);
        
    clientContext.load(collListItem, 'Include(Id, DisplayName)');
        
    clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));        
        
}

function onQuerySucceeded(sender, args) {

    var listItemInfo = '';

    var listItemEnumerator = collListItem.getEnumerator();
        
    while (listItemEnumerator.moveNext()) {
        var oListItem = listItemEnumerator.get_current();
        listItemInfo += '\nID: ' + oListItem.get_id() + 
            '\nDisplay name: ' + oListItem.get_displayName();
    }

    alert(listItemInfo.toString());
}

function onQueryFailed(sender, args) {

    alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

How to update list items

To modify a list item you can specify the column value to change through an indexer, and just as for other objects, call Update() (JavaScript: update()) before calling ExecuteQuery() or ExecuteQueryAsync(ClientRequestSucceededEventHandler, ClientRequestFailedEventHandler) (JavaScript: executeQueryAsync(succeededCallback, failedCallback)). The following example changes the title of the item that has the specified ID.

ClientContext clientContext =  new ClientContext("http://MyServer/sites/MySiteCollection");
Web oWebsite = clientContext.Web;
ListCollection collList = oWebsite.Lists;

List oList = collList.GetByTitle("My List");
ListItem oItem = oList.GetItemById(5);
oItem["Title"] = "Hello World";
oItem.Update();

clientContext.ExecuteQuery();
Dim clientContext As New ClientContext("http://MyServer/sites/MySiteCollection")
Dim oWebsite As Web = clientContext.Web
Dim collList As ListCollection = oWebsite.Lists

Dim oList As List = collList.GetByTitle("My List")

Dim oItem As ListItem = oList.GetItemById(5)
oItem("Title") = "Hello World"
oItem.Update()

clientContext.ExecuteQuery()
function updateListItem() {

    var clientContext = new SP.ClientContext('sites/MySiteCollection');
    var oList = clientContext.get_web().get_lists().getByTitle('My List');

    this.oListItem = oList.getItemById(5);
    oListItem.set_item('Title', 'Hello World');
    oListItem.update();

    clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}

function onQuerySucceeded() {

    alert('Item updated.');
}

function onQueryFailed(sender, args) {

    alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

Asynchronous Processing

Both the JavaScript version of the object model and the Silverlight version (when it modifies the UI) use asynchronous processing. Consequently, the ExecuteQueryAsync(ClientRequestSucceededEventHandler, ClientRequestFailedEventHandler) method (JavaScript: executeQueryAsync(succeededCallback, failedCallback)) includes passing delegates for callback methods to handle query success and failure. When this asynchronous method completes processing, the specified callback method is called, and the client retrieves data from the server. To execute a query using the JavaScript or Silverlight object model, define a delegate that has the same signature as a callback method, and extend the call path by passing the delegate as a parameter in ExecuteQueryAsync(ClientRequestSucceededEventHandler, ClientRequestFailedEventHandler) (JavaScript: executeQueryAsync(succeededCallback, failedCallback)).

The following example illustrates asynchronous processing in JavaScript and Silverlight. The first method, retrieveWebsite, obtains an object for the current Web site, which becomes available to the specified callback method, onQuerySucceeded, for which the delegate is passed in ExecuteQueryAsync(ClientRequestSucceededEventHandler, ClientRequestFailedEventHandler) (JavaScript: executeQueryAsync(succeededCallback, failedCallback)). The callback method gets and sets the title of the retrieved Web site object, and calls the query execution method a second time for update to take effect.

var oWebsite;
var clientContext;

function retrieveWebsite()
{
   clientContext = SP.ClientContext.get_current();
   oWebsite = clientContext.get_web();
   clientContext.load(oWebsite);
   clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed);
} 
 
function onQuerySucceeded()
{
   oWebsite.set_title(oWebsite.get_title() + " changed in ECMAScript.");
   oWebsite.update();
   clientContext.executeQueryAsync();
}

The following example shows how to set the Web site title similarly by using the Silverlight object model.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.SharePoint.Client;

namespace Microsoft.SDK.SharePointServices.Samples
{
    public partial class MainPage : UserControl
    {
        ClientContext clientContext;
        Web oWebsite;

        public MainPage()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            clientContext = ClientContext.Current;
            oWebsite = clientContext.Web;

            clientContext.Load(oWebsite,
                website=>website.Title);

            clientContext.ExecuteQueryAsync(onQuerySucceeded, onQueryFailed);
        }

        private void onQuerySucceeded(object sender, ClientRequestSucceededEventArgs args)
        {
            UpdateUIMethod updateUI = ChangeTitle;
            this.Dispatcher.BeginInvoke(updateUI);
        }

        private void ChangeTitle()
        {
            oWebsite.Title = oWebsite.Title + " changed in Silverlight.";
            oWebsite.Update();

            clientContext.ExecuteQueryAsync(onTitleChanged, onQueryFailed);
        }

        private void onTitleChanged(object sender, ClientRequestSucceededEventArgs args)
        {
            UpdateUIMethod updateUI = DisplayTitle;
            this.Dispatcher.BeginInvoke(updateUI);
        }

        private void DisplayTitle()
        {
            MessageBox.Show("Title changed to " + oWebsite.Title);
        }

        private void onQueryFailed(object sender, ClientRequestFailedEventArgs args)
        {
            MessageBox.Show("Request failed. " + args.Message + "\n" + args.StackTrace);
        }

        private delegate void UpdateUIMethod();
    }
}

Both the JavaScript and Silverlight examples use the Current property (JavaScript: current) of the client context to specify the current request context, instead of using the ClientContext(String) constructor (JavaScript: ClientContext(serverRelativeUrl)) and specifying a URL.

For other examples and information about data retrieval in the context of the SharePoint Foundation Silverlight object model, see Using the Silverlight Object Model.

See Also

Concepts

How to: Work with Websites

How to: Retrieve Lists

How to: Retrieve List Items

How to: Work with Users and Groups

Client Context as Central Object

Client Objects, Value Objects, and Scalar Properties

SharePoint Client Object Creation

SharePoint 2010 Client Object Model Guidelines

Differences Between Managed and JavaScript Object Models

Common Programming Tasks in the Managed Client Object Model

Other Resources

Client Class Library

JavaScript Class Library

Using the SharePoint Foundation 2010 Managed Client Object Model

Client Object Model Resource Center