Поделиться через


Проекции запросов (службы WCF Data Services)

Проекция предоставляет службам Протокол Open Data Protocol (OData) механизм для уменьшения объема данных в канале, возвращаемых запросом при указании, что в ответе возвращаются только определенные свойства сущности. Дополнительные сведения см. в разделе OData.

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

Определение проекции запроса

Предложение проекции можно добавить в запрос, используя либо параметр запроса $select в URI, либо предложение select (Select в Visual Basic) в запросе LINQ. Возвращаемые данные сущности могут быть проецированы в типы сущностей или в несущностные типы на дочернем объекте. В примерах этого раздела показано, как использовать предложение select в запросе LINQ.

Ee473425.Important(ru-ru,VS.100).gif Примечание
При сохранении обновлений, выполненных в проецируемых типах, в службе данных может произойти потеря данных.Дополнительные сведения см. в разделе Projection Considerations.

Требования к типам сущностей и несущностным типам

Типы сущностей должны содержать одно или несколько свойств идентификатора, которые составляют ключ сущности. Типы сущностей определяются на клиентах одним из следующих способов.

  • Применением атрибута DataServiceKeyAttribute или DataServiceEntityAttribute к типу.

  • Если тип имеет свойство, именуемое ID.

  • Если тип имеет свойство, именуемое typeID, где type является именем типа.

По умолчанию, если результаты запроса проецируются на тип, определенный на клиенте, свойства, запрашиваемые в проекции, должны существовать в типе клиента. Но если задается значение true для свойства IgnoreMissingProperties для DataServiceContext, не требуется, чтобы свойства, заданные в проекции, были в типе клиента.

Выполнение обновлений спроецированных результатов

При выполнении проекции результатов запроса на типы сущностей объект DataServiceContext может отслеживать объекты с обновлениями, которые должны передаваться вновь в службу данных, если вызывается метод SaveChanges. Однако обновления, выполненные в данных, проецируемых на клиенте на несущностные типы, не могут передаваться обратно в службу данных. Это является следствием того, что без ключа для идентификации экземпляра сущности служба данных не может обновить правильную сущность в источнике данных. Несущностные типы не прикрепляются к объекту DataServiceContext.

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

Создание проецируемых типов

В следующем примере используется анонимный запрос LINQ, который проецирует связанные с адресом свойства типа Customers в новый тип CustomerAddress, как определено на клиенте, и помечается как тип сущности.

' Define an anonymous LINQ query that projects the Customers type into 
' a CustomerAddress type that contains only address properties.
Dim query = From c In context.Customers _
                Where c.Country = "Germany" _
                Select New CustomerAddress With { _
                    .CustomerID = c.CustomerID, _
                    .Address = c.Address, _
                    .City = c.City, _
                    .Region = c.Region, _
                    .PostalCode = c.PostalCode, _
                    .Country = c.Country}
// Define an anonymous LINQ query that projects the Customers type into 
// a CustomerAddress type that contains only address properties.
var query = from c in context.Customers
            where c.Country == "Germany"
            select new CustomerAddress { 
                CustomerID = c.CustomerID, 
                Address = c.Address, 
                City = c.City, 
                Region = c.Region,
                PostalCode = c.PostalCode, 
                Country = c.Country};

В этом примере шаблон инициализатора объекта используется для создания нового экземпляра типа CustmerAddress вместо вызова конструктора. При проецировании в типы сущностей конструкторы не поддерживаются, но они могут использоваться при проецировании в несущностные типы и в анонимные типы. Поскольку CustomerAddress имеет тип сущности, изменения могут быть сделаны и отправлены обратно в службу данных.

Кроме того, данные из типа Customer проецируются в экземпляр типа сущности CustomerAddress, а не в анонимный тип. Проецирование в типы сущностей поддерживается, но данные доступны только для чтения, поскольку анонимные типы рассматриваются как несущностные типы.

Параметры MergeOption объекта DataServiceContext используются для разрешения идентификатора во время проекции запроса. Это означает, что, если экземпляр типа Customer уже существует в объекте DataServiceContext, экземпляр CustomerAddress с тем же идентификатором будет следовать правилам разрешения идентификатора, установленным параметром MergeOption

В следующей таблице описаны особенности поведения при проецировании результатов в типы сущностей и в типы несущностей.

Действие Тип сущности Несущностные типы

Создание нового спроецированного экземпляра с использованием инициализаторов, как в следующем примере:

Dim query = From c In context.Customers _
                Where c.Country = "Germany" _
                Select New CustomerAddress With { _
                    .CustomerID = c.CustomerID, _
                    .Address = c.Address, _
                    .City = c.City, _
                    .Region = c.Region, _
                    .PostalCode = c.PostalCode, _
                    .Country = c.Country}
var query = from c in context.Customers
            where c.Country == "Germany"
            select new CustomerAddress { 
                CustomerID = c.CustomerID, 
                Address = c.Address, 
                City = c.City, 
                Region = c.Region,
                PostalCode = c.PostalCode, 
                Country = c.Country};

Поддерживается

Поддерживается

Создание нового спроецированного экземпляра с использованием конструкторов, как в следующем примере:

Dim query = From c In context.Customers _
                Where c.Country = "Germany" _
                Select New CustomerAddress( _
                c.CustomerID, _
                c.Address, _
                c.City, _
                c.Region, _
                c.PostalCode, _
                c.Country)
var query = from c in context.Customers
            where c.Country == "Germany"
            select new CustomerAddress(
            c.CustomerID, 
            c.Address, 
            c.City, 
            c.Region,
            c.PostalCode, 
            c.Country);

Вызывается исключение NotSupportedException.

Поддерживается

Использование проекции для преобразования значения свойства, как в следующем примере:

Dim query = From c In context.Customers _
                Where c.Country = "Germany" _
                Select New CustomerAddress With _
                {.CustomerID = c.CustomerID, _
                    .Address = "Full address: " & c.Address & ", " & _
                    c.City & "," & c.Region & " " & c.PostalCode, _
                    .City = c.City, _
                    .Region = c.Region, _
                    .PostalCode = c.PostalCode, _
                    .Country = c.Country}
var query = from c in context.Customers
            where c.Country == "Germany"
            select new CustomerAddress
            {
                CustomerID = c.CustomerID, 
                Address = "Full address:" + c.Address + ", " +
                c.City + ", " + c.Region + " " + c.PostalCode,
                City = c.City,
                Region = c.Region,
                PostalCode = c.PostalCode,
                Country = c.Country
            };

Это преобразование не поддерживается для типов сущностей, поскольку оно может вести к путанице, а также к возможной переписи данных в источнике данных, который относится к другой сущности.

Вызывается исключение NotSupportedException.

Поддерживается

Вопросы проекции

При определении проекции запроса следует учитывать следующие дополнительные соображения.

  • При определении специализированных каналов для формата Atom необходимо убедиться, что все свойства сущности, которые имеют определенные пользовательские сопоставления, включены в проекцию. Если сопоставленное свойство сущности не включено в проекцию, может произойти потеря данных. Дополнительные сведения см. в разделе Настройка канала (службы WCF Data Services).

  • Если вставки выполняются в проецированный тип, который не содержит все свойства сущности в модели данных службы данных, свойства, не включенные в проекцию на клиенте, устанавливаются в их значения по умолчанию.

  • Если обновления выполняются в проецированном типе, который не содержит все свойства сущности в модели данных службы данных, существующие значения, не включенные в проекцию на клиенте, будут переписаны инициализированными значениями по умолчанию.

  • Если проекция включает сложное свойство, должен быть возвращен весь сложный объект.

  • Если проекция включает свойство навигации, связанные объекты загружаются неявно, без вызова метода Expand. Метод Expand не поддерживается для использования в проецированном запросе.

  • Запросы проецирования запроса на клиенте преобразуются для использования параметра запроса $select в URI запроса. Если запрос с проекцией выполняется для предыдущей версии служб Службы WCF Data Services , которая не поддерживает параметр запроса $select, возвращается ошибка. Это может также произойти, если версия MaxProtocolVersion объекта DataServiceBehavior для службы данных установлена в значение V1. Дополнительные сведения см. в разделе Работа с несколькими версиями служб WCF Data Services.

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

См. также

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

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