Querying the Data Service (WCF Data Services/Silverlight)


In this task, you will query the data service and bind the returned entity data to controls in the application, which you defined in the previous task. You create and execute the query asynchronously by using the NorthwindEntities class, which derives from the DataServiceContext class. You generated this context class from the data service metadata by using the add service reference tool in the previous task. For more information, see Working with .NET Framework Client Libraries (WCF Data Services).

Note Note:

Because you asynchronously access the data service by using network protocols, you must use the BeginInvoke method of the Dispatcher class to correctly marshal the response operation back to the main application thread (the UI thread) of your Silverlight-based application. For more information, see Synchronizing Data for Multithreading.

To query for orders that belong to a specified customer

  1. Open the MainPage.xaml.cs source code file of the Silverlight project.

  2. Add the following using directives (Imports in Visual Basic):

    using System.Data.Services.Client;
    using System.Collections.ObjectModel;
    using System.Collections.Specialized;
    using SilverlightClient.Northwind;
  3. Add the following type definitions to the MainPage class:

    NorthwindEntities svcContext;
    ObservableCollection<Order> ordersBindingCollection;
    ObservableCollection<Order_Detail> detailsBindingCollection;
    DataServiceQueryContinuation<Order> orderToken;
    DataServiceQueryContinuation<Order_Detail> itemToken;
    Order currentOrder;
  4. In the public constructor method for the MainPage class, insert the following code that initializes the data binding collections.

    // Create the binding collections.
    ordersBindingCollection = new ObservableCollection<Order>();
    detailsBindingCollection = new ObservableCollection<Order_Detail>();
    // Initialize the tokens used to track paged responses.
    orderToken = null;
    itemToken = null;
  5. Add the following methods to the MainPage class. These methods are called when the getCustomerOrders button is clicked. The first method reinitializes the DataServiceContext and clears the binding collections. The second method obtains an instance of DataServiceQuery<TElement> of the Customers type from the context. The AddQueryOption method is called two times on this query; one time to add a $filter query option to return only a specific customer and again to add an $expand query option to return orders related to the returned customer. The returned Orders objects are loaded into an ObservableCollection<T> that is bound to the DataGrid.

    private void ResetBindingData()
        // Create a new data service context.
        svcContext =
            new NorthwindEntities(new Uri("http://localhost:12345/Northwind.svc"));
    private void getCustomerOrders_Click(object sender, RoutedEventArgs e)
        // Instantiate the data service context and clear any existing bindings.
        // Define a LINQ query to return the specifed customer and related orders.
        var query = from o in svcContext.Orders                  
                    where o.CustomerID == this.customerId.Text                  
                    select o;
            // Begin execution of the query as a DataServiceQuery.
            ((DataServiceQuery<Order>)query).BeginExecute(OnCustomerOrdersQueryComplete, query);
        catch (Exception ex)
            messageTextBlock.Text = ex.Message;
    private void OnCustomerOrdersQueryComplete(IAsyncResult result)
        // Use the Dispatcher to ensure that the 
        // asynchronous call returns in the correct thread.
        Dispatcher.BeginInvoke(() => 
                IEnumerable<Order> response = null;
                    if (orderToken != null)
                        // This is not the first page, so we get back the context.
                        svcContext = result.AsyncState as NorthwindEntities;
                        response = svcContext.EndExecute<Order>(result);
                        // Since this is the first page, we get back the query.
                        var query = result.AsyncState as DataServiceQuery<Order>;
                        // Get the response of the query.
                        response = query.EndExecute(result);
                    // Enumeration executes the query.
                    foreach (Order o in response)
                        // Add the order to the binding collection.
                    // Get the continuation token from the response.
                    orderToken = ((QueryOperationResponse<Order>)response).GetContinuation();
                    if (orderToken != null)
                        // Get the next page if a continuation token was returned.
                            OnCustomerOrdersQueryComplete, svcContext);
                        // There are no more response pages, so bind the grid control 
                        // to the collection and update the layout.
                        this.ordersGrid.DataContext = ordersBindingCollection;
                        // Hide the relationship property columns.
                        this.ordersGrid.Columns[0].Visibility = Visibility.Collapsed;
                        this.ordersGrid.Columns[1].Visibility = Visibility.Collapsed;
                        this.ordersGrid.Columns[2].Visibility = Visibility.Collapsed;
                        this.ordersGrid.Columns[11].Visibility = Visibility.Collapsed;
                        this.ordersGrid.Columns[14].Visibility = Visibility.Collapsed;
                        this.ordersGrid.Columns[15].Visibility = Visibility.Collapsed;
                        // Select the first order, if any orders exist.
                        if (ordersBindingCollection.Count > 0)
                            this.ordersGrid.SelectedIndex = 0;
                catch (DataServiceQueryException ex)
                    this.messageTextBlock.Text = string.Format("Error: {0} - {1}",
                        ex.Response.StatusCode.ToString(), ex.Response.Error.Message);

To build and run the application

  1. From the Debug menu, select Start Debugging or Start Without Debugging.

    This builds and starts the application.

  2. When the page loads, enter a value in the Customer ID text box (a valid value of ALFKI is provided), and then click Get Orders.

    This displays the orders that belong to that customer.

You have successfully created a query that returns a specific Customers object and related Orders objects from the Northwind data service, and you have bound those Orders objects to a grid control. Next, you will load specific Order_Details objects from the data service and bind them to a second data grid:

Loading Related Entities

Community Additions