Загрузка отложенного содержимого (службы WCF Data Services)

По умолчанию Службы WCF Data Services ограничивает объем данных, возвращаемых запросом. Однако существует возможность явной загрузки из службы данных при необходимости дополнительных данных, включая связанные сущности, разбитые на страницы данные ответа и потоки двоичных данных. Этот раздел описывает загрузку такого отложенного содержимого в приложении.

Связанные сущности

При выполнении запроса возвращаются только сущности в адресованном наборе сущностей. Например, когда запрос к службе данных Northwind возвращает сущности Customers, по умолчанию возврат связанных сущностей Orders не происходит, несмотря на наличие связи между сущностями Customers и Orders. Кроме того, если в службе данных включена подкачка, необходимо явно загружать последующие страницы данных из службы. Существует два способа загрузки связанных сущностей.

  • Безотложная загрузка: для запроса возврата сущностей, связанных ассоциацией с набором сущностей, возвращаемых запросом, можно использовать параметр запросов $expand. Для добавления параметра $expand в запрос, отправляемый службе данных, используйте метод Expand класса DataServiceQuery. Несколько связанных наборов сущностей можно запросить, разделяя их запятыми, как показывает следующий пример. Все сущности, запрашиваемые в запросе, возвращаются в одном ответе. Следующий пример возвращает сущности Order_Details и Customers вместе с набором сущностей 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 ограничивают количество наборов сущностей, которые можно включить в один запрос, с помощью параметра запроса $expand двенадцатью наборами.

  • Явная загрузка: для явной загрузки связанных сущностей можно вызвать метод LoadProperty экземпляра DataServiceContext. При каждом вызове метода LoadProperty создается отдельный запрос к службе данных. Следующий пример явно загружает сущности Order_Details для сущности 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");
    

При выборе параметра помните, что придется соблюдать баланс между числом запросов к службе данных и объемом данных, возвращаемых в одном ответе. Активная загрузка используется, если приложению требуются связанные объекты и необходимо избежать дополнительной задержки, связанной с дополнительными запросами для явного извлечения данных. Однако в тех случаях, когда приложению требуются только данные для конкретных связанных экземпляров сущности, рассмотрите возможность их явной загрузки путем вызова метода LoadProperty. Дополнительные сведения см. в разделе Как загрузить связанные сущности (службы WCF Data Services).

Содержимое, разбитое на страницы

Если в службе данных включена подкачка страниц, число сущностей в канале, возвращаемом службой данных, ограничено настройками службы данных. Пределы подкачки можно задавать отдельно для каждого набора сущностей. Дополнительные сведения см. в разделе Настройка службы данных (службы WCF Data Services). Если включена подкачка страниц, то последняя запись в канале содержит ссылку на следующую страницу данных. Эта ссылка содержится в объекте DataServiceQueryContinuation. Получить URI для следующей страницы можно, вызвав метод GetContinuation объекта QueryOperationResponse, возвращенного при выполнении запроса DataServiceQuery. Возвращенный объект DataServiceQueryContinuation можно затем использовать для загрузки следующей страницы результатов. Перед вызовом метода GetContinuation результат запроса надо перечислить. Рассмотрите возможность применения цикла do…while, чтобы сначала перечислить результат запроса, а потом проверить следующее значение ссылки на non-null. Если метод GetContinuation возвращает null (Nothing в Visual Basic), дополнительные страницы результата для исходного запроса отсутствуют. Следующий пример показывает цикл do…while, который загружает разбитые на страницы данные клиентов из образца службы данных 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);

Если запрос требует возвращения связанных сущностей в одном ответе вместе с запрошенным набором сущностей, пределы разбиения на страницы могут повлиять на вложенные каналы, встроенные вместе с запросом. Например, если в образце службы данных Northwind установлен предел подкачки для набора сущностей Customers, независимый предел подкачки может быть также установлен для набора сущностей Orders, как в следующем примере из файла Northwind.svc.cs, определяющего образец службы данных 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;

В этом случае необходимо реализовать подкачку как для канала верхнего уровня Customers, так и для вложенного канала сущностей Orders. Следующий пример показывает цикл while, используемый для загрузки страниц сущностей Orders, связанных с выбранной сущностью Customers.

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();
}

Дополнительные сведения см. в разделе Как загружать результаты, разбитые на страницы (службы WCF Data Services).

Потоки двоичных данных

Службы Службы WCF Data Services позволяют обращаться к данным большого двоичного объекта (BLOB) как к потоку данных. Преобразование в поток откладывает загрузку двоичных данных до момента, когда они понадобятся, а клиент имеет возможность обработать их более эффективно. Чтобы можно было воспользоваться этой функцией, в службе данных должен быть реализован поставщик IDataServiceStreamProvider. Дополнительные сведения см. в разделе Потоковый поставщик (службы WCF Data Services). Если потоки включены, типы сущностей возвращаются без связанных двоичных данных. В этом случае для доступа к потоку данных и получения двоичных данных от службы необходимо использовать метод GetReadStream класса DataServiceContext. Аналогично можно использовать метод SetSaveStream для добавления или изменения двоичных данных сущности в виде потока. Дополнительные сведения см. в разделе Работа с двоичными данными (службы WCF Data Services).

См. также

Основные понятия

Запросы к службе данных (службы WCF Data Services)

Другие ресурсы

Клиентская библиотека служб WCF Data Services