Proyecciones de consultas (WCF Data Services)

La proyección proporciona un mecanismo en Open Data Protocol (OData) para reducir la cantidad de datos de la fuente devueltos por una consulta mediante la especificación de que solo se devuelven algunas propiedades de una entidad en la respuesta. Para obtener más información, vea OData.

En este tema se describen la definición de la proyección de una consulta, cuáles son los requisitos para los tipos con entidad y sin ella, la realización de actualizaciones en los resultados proyectados, la creación de tipos proyectados y la enumeración de algunas consideraciones de proyecciones.

Definir una proyección de consultas

Puede agregar una cláusula de proyección a una consulta mediante la opción de consulta $select en un URI o mediante la cláusula select (Select en Visual Basic) en una consulta LINQ. Los datos de la entidad devueltos se pueden proyectar en tipos de entidad o tipos sin entidad en el cliente. Los ejemplos de este tema muestran cómo usar la cláusula select en una consulta LINQ.

Ee473425.Important(es-es,VS.100).gif Nota:
Se puede producir una pérdida de datos en el servicio de datos cuando se guardan actualizaciones efectuadas en tipos proyectados.Para obtener más información, vea Projection Considerations.

Requisitos para tipos con entidad y sin ella

Los tipos de entidad deben tener una o varias propiedades de entidad que constituyen la clave de la entidad. Los tipos de entidad se definen en clientes de una de las siguientes formas:

De forma predeterminada, cuando proyecte los resultados de la consulta en un tipo definido en el cliente, las propiedades solicitadas en la proyección deben existir en el tipo de cliente. Sin embargo, cuando especifica un valor de true para la propiedad IgnoreMissingProperties de la clase DataServiceContext, es necesario que se produzcan las propiedades especificadas en la proyección en el tipo de cliente.

Realizar actualizaciones en los resultados proyectados

Cuando proyecte los resultados de la consulta en tipos de entidad en el cliente, la clase DataServiceContext puede realizar el seguimiento de esos objetos con las actualizaciones que se van a devolver al servicio de datos cuando se llame al método SaveChanges. No obstante, las actualizaciones efectuadas en datos proyectados en entidades sin tipo en el cliente no se pueden devolver al servicio de datos. Esto se debe a que el servicio de datos no puede actualizar la entidad correcta en el origen de datos sin ninguna clave que identifique la instancia de la entidad. Los tipos sin identidad no se adjunta a la clase DataServiceContext.

Cuando una o varias propiedades de un tipo de entidad definido en el servicio de datos no se producen en el tipo de cliente en el que se proyecta la entidad, las inserciones de nuevas entidades no contendrán estas propiedades que faltan. En este caso, las actualizaciones realizadas en entidades existentes tampoco incluirán estas propiedades que faltan. Cuando un valor existe para tal propiedad, la actualización la restablece en el valor predeterminado de la propiedad, de la forma definida en el origen de datos.

Crear tipos proyectados

En el siguiente ejemplo se usa una consulta LINQ anónima que proyecta propiedades de relacionadas con la dirección del tipo Customers en un nuevo tipo CustomerAddress, que se define en el cliente y al que se le puede dar el atributo de tipo de entidad:

' 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};

En este ejemplo, se usa el modelo de inicializador de objeto para crear una nueva instancia del tipo CustmerAddress en vez de llamar a un constructor. No se admiten constructores cuando se realizan proyecciones en tipos de entidad, pero se pueden usar al realizar proyecciones en tipos sin entidad y anónimos. Puesto que CustomerAddress es un tipo de entidad, los cambios se pueden efectuar en el servicio de datos y devolvérselos a él.

Asimismo, los datos de tipo Customer se proyectan en una instancia del tipo de entidad CustomerAddress en vez de en un tipo anónimo. Se admiten las proyecciones en tipos anónimos, pero los datos son de solo lectura porque los tipos anónimos se tratan como tipos sin entidad.

La configuración de la enumeración MergeOption de la clase DataServiceContext se usa para identificar la resolución durante la proyección de la consulta. Es decir, si una instancia del tipo Customer ya existe en la clase DataServiceContext, una instancia de CustomerAddress con la misma identidad seguirá las reglas de resolución de entidades establecidas por la enumeración MergeOption.

En la siguiente tabla se describen los comportamientos cuando se proyectan resultados en tipos con entidad y sin ella:

Acción Tipo con entidad Tipo sin entidad

Crear una nueva instancia proyectada mediante inicializadores, como en el ejemplo siguiente:

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

Admitida

Admitida

Crear una nueva instancia proyectada con constructores, como en el ejemplo siguiente:

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

Se inicia una clase NotSupportedException.

Admitida

Usar una proyección para transformar un valor de propiedad, como en el ejemplo siguiente:

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

Esta transformación no la admiten los tipos de entidad porque puede confundir y posiblemente sobrescribir los datos en el origen de datos que pertenece a otra entidad.

Se inicia una clase NotSupportedException.

Admitida

Consideraciones sobre proyecciones

Se aplican las siguiente consideraciones adicionales cuando se define una proyección de consultas.

  • Cuando defina las fuentes personalizadas para el formato Atom, debe asegurarse de que se incluyan todas las propiedades de entidad con asignaciones personalizadas en la proyección. Cuando no se incluya ninguna propiedad de entidad asignada en la proyección, se puede producir la pérdida de datos. Para obtener más información, vea Personalización de fuentes (WCF Data Services).

  • Cuando se realicen inserciones en un tipo proyectado que no contenga todas las propiedades de la entidad en el modelo de datos del servicio de datos, las propiedades no incluidas en la proyección en el cliente se establecen en sus valores predeterminados.

  • Cuando se realicen actualizaciones en un tipo proyectado que no contenga todas las propiedades de la entidad en el modelo de datos del servicio de datos, los valores existentes no incluidos en la proyección en el cliente se sobrescribirán con valores predeterminados sin inicializar.

  • Cuando una proyección incluya una propiedad compleja, se debe devolver todo el objeto complejo.

  • Cuando una proyección incluya una propiedad de navegación, los objetos relacionados se cargan implícitamente sin tener que llamar al método Expand. No se admite el método Expand para su uso en una consulta proyectada.

  • Las consultas de proyecciones de consultas en el cliente se traducen para usar la opción de consulta $select en el URI de solicitud. Cuando se ejecute una consulta con proyección en una versión previa de WCF Data Services que no admita la opción de consulta $select, se devuelve un error. Esto también puede ocurrir cuando se establece la propiedad MaxProtocolVersion de la clase DataServiceBehavior para el servicio de datos en el valor de la enumeración V1. Para obtener más información, vea Trabajar con varias versiones de WCF Data Services.

Para obtener más información, vea Cómo: Proyectar los resultados de una consulta (WCF Data Services).

Vea también

Conceptos

Consultar el servicio de datos (WCF Data Services)