Cargar contenido aplazado (WCF Data Services)

De forma predeterminada, WCF Data Services limita el número de datos que devuelve una consulta. Sin embargo, es posible cargar explícitamente datos adicionales, incluidos los datos de la respuesta paginados, las entidades relacionadas y los flujos de datos binarios, del servicio de datos cuando sea necesario. En este tema se describe cómo cargar dicho contenido aplazado en una aplicación.

Entidades relacionadas

Cuando se ejecuta una consulta, solo se devuelven las entidades pertenecientes al conjunto de entidades direccionado. Por ejemplo, cuando una consulta al servicio de datos de Northwind devuelve entidades Customers, no se devuelven de forma predeterminada las entidades relacionadas Orders, aunque haya una relación entre Customers y Orders. Además, cuando está habilitada la paginación en el servicio de datos, debe cargar explícitamente las páginas de datos subsiguientes del servicio. Hay dos maneras de cargar las entidades relacionadas:

  • Carga diligente: puede usar la opción de consulta $expand para solicitar que la consulta devuelva entidades que están relacionadas mediante una asociación con el conjunto de entidades solicitado por la consulta. Utilice el método Expand en DataServiceQuery para agregar la opción $expand a la consulta que se envía al servicio de datos. Puede solicitar varios conjuntos de entidades relacionados separándolos mediante comas, como muestra el ejemplo siguiente. Todas las entidades solicitadas por la consulta se devuelven en una única respuesta. En el ejemplo siguiente se devuelve Order_Details y Customers junto con el conjunto de entidades Orders:

    ' Define a query for orders that also returns items and customers.
    Dim query As DataServiceQuery(Of Order) = _
    context.Orders.Expand("Order_Details,Customer")
    
    // Define a query for orders that also returns items and customers.
    DataServiceQuery<Order> query =
        context.Orders.Expand("Order_Details,Customer");
    

    WCF Data Services limita a 12 el número de conjuntos de entidades que se pueden incluir en una única consulta utilizando la opción de consulta $expand.

  • Carga explícita: puede llamar al método LoadProperty de la instancia de DataServiceContext para cargar explícitamente las entidades relacionadas. Cada llamada al método LoadProperty crea una solicitud independiente al servicio de datos. En el ejemplo siguiente se carga explícitamente Order_Details para una entidad Orders:

    ' Explicitly load the order details for each order.
    context.LoadProperty(order, "Order_Details")
    
    // Explicitly load the order details for each order.
    context.LoadProperty(order, "Order_Details");
    

Al considerar qué opción se debe usar, observe que hay una correlación entre el número de solicitudes al servicio de datos y la cantidad de datos devueltos en una sola respuesta. Use la carga diligente cuando su aplicación requiera objetos asociados y desee evitar la latencia agregada de las solicitudes adicionales para recuperarlos explícitamente. Sin embargo, si hay casos en que la aplicación solo necesita los datos para determinadas instancias de entidades relacionadas, debería plantearse cargar explícitamente esas entidades llamando al método LoadProperty. Para obtener más información, vea Cómo: Cargar entidades relacionadas (WCF Data Services).

Contenido paginado

Si la paginación está habilitada en el servicio de datos, la configuración del servicio de datos limita el número de entradas de la fuente que devuelve el servicio de datos. Los límites de página pueden establecerse por separado para cada conjunto de entidades. Para obtener más información, vea Configurar el servicio de datos (WCF Data Services). Si está habilitada la paginación, la última entrada de la fuente contiene un vínculo a la página de datos siguiente. Este vínculo está contenido en un objeto DataServiceQueryContinuation. El URI a la página de datos siguiente se obtiene llamando al método GetContinuation del objeto QueryOperationResponse que se obtiene cuando se ejecuta DataServiceQuery. A continuación, el objeto DataServiceQueryContinuation devuelto se usa para cargar la página de resultados siguiente. Debe enumerar los resultados de la consulta antes de llamar al método GetContinuation. Considere la posibilidad de usar un bucle do…while para enumerar el resultado de la consulta primero y, a continuación, comprobar el valor de un vínculo siguiente non-null. Cuando el método GetContinuation devuelve null (Nothing en Visual Basic), no hay ninguna página de resultados adicional para la consulta original. En el ejemplo siguiente se muestra un bucle do…while que carga los datos del cliente paginados del servicio de datos de ejemplo Northwind.

' With a paged response from the service, use a do...while loop 
' to enumerate the results before getting the next link.
Do
    ' Write the page number.
    Console.WriteLine("Page {0}:", pageCount + 1)

    ' If nextLink is not null, then there is a new page to load.
    If token IsNot Nothing Then
        ' Load the new page from the next link URI.
        response = CType(context.Execute(Of Customer)(token),  _
        QueryOperationResponse(Of Customer))
    End If

    ' Enumerate the customers in the response.
    For Each customer As Customer In response
        Console.WriteLine("\tCustomer Name: {0}", customer.CompanyName)
    Next

    ' Get the next link, and continue while there is a next link.
    token = response.GetContinuation()
Loop While token IsNot Nothing
// With a paged response from the service, use a do...while loop 
// to enumerate the results before getting the next link.
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);

Cuando una consulta solicita que se devuelvan las entidades relacionadas en una respuesta única junto con el conjunto de entidades solicitado, los límites de paginación pueden afectar a las fuentes anidadas que están incluidas alineadas con la respuesta. Por ejemplo, cuando se establece un límite de paginación en el servicio de datos de ejemplo Northwind para el conjunto de entidades Customers, también puede establecerse un límite de paginación independiente para el conjunto de entidades Orders relacionado, como en el ejemplo siguiente del archivo Northwind.svc.cs que define el servicio de datos de ejemplo Northwind.

' Set page size defaults for the data service.
config.SetEntitySetPageSize("Orders", 20)
config.SetEntitySetPageSize("Order_Details", 50)
config.SetEntitySetPageSize("Products", 50)

' Paging requires v2 of the OData protocol.
config.DataServiceBehavior.MaxProtocolVersion = _
    System.Data.Services.Common.DataServiceProtocolVersion.V2
// Set page size defaults for the data service.
config.SetEntitySetPageSize("Orders", 20);
config.SetEntitySetPageSize("Order_Details", 50);
config.SetEntitySetPageSize("Products", 50);

// Paging requires v2 of the OData protocol.
config.DataServiceBehavior.MaxProtocolVersion =
    System.Data.Services.Common.DataServiceProtocolVersion.V2;

En este caso, debe implementar la paginación para las dos fuentes de entidades, la de nivel superior, Customers, y las anidadas, Orders. En el ejemplo siguiente se muestra el bucle while que se usa para cargar las páginas de las entidades Orders relacionadas con una entidad Customers seleccionada.

While nextOrdersLink IsNot Nothing
    For Each o As Order In c.Orders
        ' Print out the orders.
        Console.WriteLine("\t\tOrderID: {0} - Freight: ${1}", _
                o.OrderID, o.Freight)
    Next
    ' Load the next page of Orders.
    Dim ordersResponse = _
    context.LoadProperty(c, "Orders", nextOrdersLink)
    nextOrdersLink = ordersResponse.GetContinuation()
End While
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();
}

Para obtener más información, vea Cómo: Cargar resultados paginados (WCF Data Services).

Flujos de datos binarios

WCF Data Services le permite tener acceso a datos de objetos binarios grandes (BLOB) en forma de flujo de datos. La transmisión por secuencias aplaza la carga de datos binarios hasta que se necesita, y el cliente puede procesar estos datos más eficazmente. Para aprovecharse de esta funcionalidad, el servicio de datos debe implementar el proveedor IDataServiceStreamProvider. Para obtener más información, vea Proveedores de transmisión por secuencias (WCF Data Services). Cuando está habilitada la transmisión por secuencias, los tipos de entidad se devuelven sin los datos binarios relacionados. En este caso, debe usar el método GetReadStream de la clase DataServiceContext para tener acceso al flujo de datos para los datos binarios del servicio. De igual forma, use el método SetSaveStream para agregar o cambiar los datos binarios de una entidad como un flujo. Para obtener más información, vea Trabajar con datos binarios (Servicios de datos de WCF).

Vea también

Conceptos

Consultar el servicio de datos (WCF Data Services)

Otros recursos

Biblioteca de cliente de WCF Data Services