Explit Query Execution

Description and code samples
Table of Contents
Description

The Execute method is used to query a data service by URI (absolute or relative) and invoking the method causes an HTTP GET request to be issued to the data service.

The request URI specified can be absolute or relative.

Identity resolution and full object materialization for a specified entity in the response only occurs until it is enumerated.

When the URI used is absolute, the Execute method validates if the URI points to the same data service that was specified when constructing the DataServiceContext.

By default, WCF Data Services only returns data that is explicitly selected by the query URI.

Operations
Simple query execution
How to do it
// Define a request URI that returns Customers.
Uri customersUri = new Uri("Customers", UriKind.Relative);

// Create the DataServiceContext using the service URI.
DataServiceContext context = new DataServiceContext(new Uri("http://localhost/TrainingService1/"));

try
{
    // Enumerate over the query result.
    foreach (Customer customer in context.Execute<Customer>(customersUri))
    {
        Console.WriteLine("Customer Name: {0}", customer.CompanyName);
    }
}
catch (DataServiceQueryException ex)
{
    throw new ApplicationException("An error occurred during query execution.", ex);
}
Request COUNT information when executing

The DataServcieContext::IncludeTotalCount method must be first invoked.

This is equivalent to include the $inlinecount query option in the query URI.

How to do it
// Create the DataServiceContext using the service URI.
TrainingEntities context = new TrainingEntities(new Uri("http://localhost/TrainingService1/"));

// Define a new query for Customers that includes the total count.
DataServiceQuery<Customer> query = context.Customers.IncludeTotalCount();

try
{
    // Execute the query for all customers and get the response object.
    QueryOperationResponse<Customer> response = query.Execute() as QueryOperationResponse<Customer>;

    // Retrieve the total count from the response.
    Console.WriteLine("There are a total of {0} customers.", response.TotalCount);

    // Enumerate the customers in the response.
    foreach (Customer customer in response)
    {
        Console.WriteLine("\tCustomer Name: {0}", customer.CompanyName);
    }
}
catch (DataServiceQueryException ex)
{
    throw new ApplicationException("An error occurred during query execution.", ex);
}
Deferred execution: Eager loading related entities

In order to load additional information of related entites must be explicitly requested by through the method DataServiceQuery::Expand in order to add the query option “$expand” option to the query that is sent to the data service.

Multiple related entity sets can be requested by separating the expand string by a comma.

How to do it
// Define a query for orders that also returns items and customers.
DataServiceQuery<Order> query = context.Orders.Expand("Order_Details,Customer");
Deferred execution: Explicitly loading related entities

The method DataServiceContext::LoadProperty can be used to explicitly load related entities.
Each call to the method creates a separate network request to the data service.

If the property is already loaded, calling this method refresh the value of the property.

How to do it
// Create the DataServiceContext using the service URI.
DataServiceContext context = new DataServiceContext(new Uri("http://localhost/TrainingService1/"));

try
{
    // Enumerate over the top 10 orders obtained from the context.
    foreach (Order order in context.Orders.Take(10))
    {
        // Explicitly load the customer for each order.
        QueryOperationResponse response = context.LoadProperty(order, "Customer");

        // Write out customer and order information.
        Console.WriteLine("Customer: {0} - Order ID: {1}",
            order.Customer.CompanyName, order.OrderID);
    }
}
catch (DataServiceQueryException ex)
{
    throw new ApplicationException("An error occurred during query execution.", ex);
}
Deferred execution: Load paged content

In order to load paged content it must be enabled at configuration of the data service, as well as the number of entries in the feed.

This configuration can be set separately for each entity.

When paging is enabled, the final entry in the feed contains a link to the next page of data. This link is contained in a DataServiceQueryContinuation object within the QueryOperationResponse object returned when the query is executed, and can be obtained calling the QueryOperationResponse::GetContinuation method.

To process a paged content the following steps must be followed:

  1. Enable paged content loading at configuration level and configure limits per entitiy set
  2. Send request to the service
  3. Enumerate the query result (e.g. through a do..while loop)
  4. Check for a non-null next link value on the response object throuhg a call to the GetContinuation method
  5. Obtain the link for the next page and return to step 1
How to do it

Sample 1:

// Create the DataServiceContext using the service URI.
DataServiceContext context = new DataServiceContext(new Uri("http://localhost/TrainingService1/"));
DataServiceQueryContinuation<Customer> token = null;
int pageCount = 0; 

try
{
    // Execute the query for all customers and get the response object.
    QueryOperationResponse<Customer> response = context.Customers.Execute() as QueryOperationResponse<Customer>;

    do
    {
        // Write the page number.
        Console.WriteLine("Page {0}:", pageCount++);

        // 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<Customer>(token) as QueryOperationResponse<Customer>;
        }

        // Enumerate the customers in the response.
        foreach (Customer customer in response)
        {
            Console.WriteLine("\tCustomer Name: {0}", customer.CompanyName);
        }
    }

    // Get the next link, and continue while there is a next link.
    while ((token = response.GetContinuation()) != null);
}
catch (DataServiceQueryException ex)
{
    throw new ApplicationException("An error occurred during query execution.", ex);
}

Sample 2:

// Create the DataServiceContext using the service URI.
DataServiceContext context = new DataServiceContext(new Uri("http://localhost/TrainingService1/"));
DataServiceQueryContinuation<Customer> nextLink = null;
int pageCount = 0;
int innerPageCount = 0;

try
{
    // Execute the query for all customers and related orders,
    // and get the response object.
    var response =
        context.Customers.AddQueryOption("$expand", "Orders")
        .Execute() as QueryOperationResponse<Customer>;

    do
    {
        // Write the page number.
        Console.WriteLine("Customers Page {0}:", ++pageCount);

        // If nextLink is not null, then there is a new page to load.
        if (nextLink != null)
        {
            // Load the new page from the next link URI.
            response = context.Execute<Customer>(nextLink)
                as QueryOperationResponse<Customer>;
        }

        // Enumerate the customers in the response.
        foreach (Customer c in response)
        {
            Console.WriteLine("\tCustomer Name: {0}", c.CompanyName);
            Console.WriteLine("\tOrders Page {0}:", ++innerPageCount);

            // Get the next link for the collection of related Orders.
            DataServiceQueryContinuation<Order> nextOrdersLink =
                response.GetContinuation(c.Orders);

            while (nextOrdersLink != null)
            {
                foreach (Order o in c.Orders)
                {
                    // Print out the orders.
                    Console.WriteLine("\t\tOrderID: {0} - Freight: ${1}", o.OrderID, o.Freight);
                }

                // Load the next page of Orders.
                var ordersResponse = context.LoadProperty(c, "Orders", nextOrdersLink);
                nextOrdersLink = ordersResponse.GetContinuation();
            }
        }
    }

    // Get the next link, and continue while there is a next link.
    while ((nextLink = response.GetContinuation()) != null);
}
catch (DataServiceQueryException ex)
{
    throw new ApplicationException("An error occurred during query execution.", ex);
}