Partager via


Projections de requête (WCF Data Services)

La projection fournit un mécanisme dans le protocole Protocole OData (Open Data) permettant de réduire la quantité de données retournées dans le flux par une requête en spécifiant que seules certaines propriétés d'une entité doivent être retournées dans la réponse. Pour plus d'informations, consultez OData (en anglais).

Cette rubrique décrit comment définir une projection de requête, quelles sont les conditions pour les types d'entité et de non-entité, la mise à jour des résultats projetés, la création des types projetés et répertorie des considérations relatives à la projection.

Définition d'une projection de requête

Vous pouvez ajouter une clause de projection à une requête en utilisant l'option de requête $select dans un URI ou en utilisant la clause select (Select dans Visual Basic) dans une requête LINQ. Les données d'entité retournées peuvent être projetées dans des types d'entité ou de non-entité sur le client. Les exemples de cette rubrique montrent comment utiliser la clause select dans une requête LINQ.

Ee473425.Important(fr-fr,VS.100).gif Remarque :
Une perte de données peut survenir dans le service de données lorsque vous enregistrez des mises à jour apportées aux types projetés.Pour plus d'informations, consultez Projection Considerations.

Conditions requises pour les types d'entité et de non-entité

Les types d'entité doivent avoir une ou plusieurs propriétés d'identité qui composent la clé d'entité. Les types d'entité sont définis sur les clients de l'une des manières suivantes :

Par défaut, lorsque vous projetez des résultats de requête dans un type défini sur le client, les propriétés demandées dans la projection doivent exister dans le type de client. Toutefois, lorsque vous spécifiez une valeur true pour la propriété IgnoreMissingProperties de DataServiceContext, il n'est pas requis que les propriétés spécifiées dans la projection se produisent dans le type de client.

Mise à jour des résultats projetés

Lorsque vous projetez des résultats de requête dans des types d'entité sur le client, DataServiceContext peut suivre ces objets avec les mises à jour à renvoyer au service de données lorsque la méthode SaveChanges est appelée. Toutefois, les mises à jour apportées aux données projetées dans des types de non-entité sur le client ne peuvent pas être renvoyées au service de données. La cause est que sans une clé pour identifier l'instance d'entité, le service de données ne peut pas mettre à jour l'entité correcte dans la source de données. Les types de non-entité ne sont pas joints à DataServiceContext.

Lorsqu'une ou plusieurs propriétés d'un type d'entité défini dans le service de données ne se produit pas dans le type de client dans lequel l'entité est projetée, les insertions de nouvelles entités ne contiennent pas ces propriétés manquantes. Dans ce cas, les mises à jour apportées aux entités existantes n'incluent pas non plus ces propriétés manquantes. Lorsqu'une valeur existe pour une telle propriété, la mise à jour rétablit la valeur par défaut de la propriété, comme défini dans la source de données.

Création de types projetés

L'exemple suivant utilise une requête LINQ anonyme qui projette les propriétés associées à l'adresse du type Customers dans un nouveau type CustomerAddress, qui est défini sur le client et est attribué comme un type d'entité :

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

Dans cet exemple, le modèle de l'initialiseur d'objet est utilisé pour créer une nouvelle instance de type CustmerAddress au lieu d'appeler un constructeur. Les constructeurs ne sont pas pris en charge lors de la projection dans des types d'entité, mais ils peuvent être utilisés pour les projections dans des types de non-entité et anonymes. Étant donné que CustomerAddress est un type d'entité, les modifications peuvent être apportées et renvoyées au service de données.

De même, les données de type Customer sont projetées dans une instance du type d'entité CustomerAddress au lieu d'un type anonyme. La projection dans des types anonymes est prise en charge, mais les données sont en lecture seule parce que les types anonymes sont traités comme des types de non-entité.

Les paramètres de MergeOption de DataServiceContext sont utilisés pour la résolution de l'identité pendant la projection de la requête. Cela signifie que si une instance de type Customer existe déjà dans DataServiceContext, une instance CustomerAddress avec la même identité suit les règles de résolution de l'identité définies par MergeOption

Le tableau suivant décrit les comportements lors de la projection de résultats dans les types d'entité et de non-entité :

Action Type d'entité Type de non entité

Création d'une nouvelle instance projetée à l'aide d'initialiseurs, comme dans l'exemple suivant :

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

Prise en charge

Prise en charge

Création d'une nouvelle instance projetée à l'aide de constructeurs, comme dans l'exemple suivant :

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 est levée.

Prise en charge

Utilisation de la projection pour transformer une valeur de propriété, comme dans l'exemple suivant :

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

Cette transformation n'est pas prise en charge pour les types d'entité car cela peut engendrer une confusion et remplacer les données de la source de données qui appartient à une autre entité.

NotSupportedException est levée.

Prise en charge

Considérations sur la projection

Les considérations supplémentaires suivantes s'appliquent à la définition d'une projection de requête.

  • Lorsque vous définissez des flux personnalisés au format Atom, vous devez vérifier que toutes les propriétés de l'entité qui ont des mappages personnalisés définis sont incluses dans la projection. Lorsqu'une propriété d'entité mappée n'est pas incluse dans la projection, une perte de données peut se produire. Pour plus d'informations, consultez Personnalisation de flux (WCF Data Services).

  • Lorsque des insertions sont apportées à un type projeté qui ne contient pas toutes les propriétés de l'entité du modèle de données du service de données, les propriétés non incluses dans la projection sur le client sont définies sur les valeurs par défaut.

  • Lorsque des mises à jour sont apportées à un type projeté qui ne contient pas toutes les propriétés de l'entité du modèle de données du service de données, les valeurs existantes non incluses dans la projection sur le client sont remplacées par les valeurs par défaut non initialisées.

  • Lorsqu'une projection inclut une propriété complexe, l'objet complexe entier doit être retourné.

  • Lorsqu'une projection inclut une propriété de navigation, les objets connexes sont chargés implicitement sans devoir appeler la méthode Expand. La méthode Expand n'est pas prise en charge pour une utilisation dans une requête projetée.

  • Les requêtes de projections de requête sur le client sont traduites pour utiliser l'option de requête $select dans l'URI de requête. Lorsqu'une requête avec projection est exécutée sur une version précédente d'Services de données WCF qui ne prend pas en charge l'option de requête $select, une erreur est retournée. Cela peut également arriver lorsque MaxProtocolVersion de DataServiceBehavior pour le service de données est défini sur une valeur V1. Pour plus d'informations, voir Utilisation de plusieurs versions de WCF Data Services.

Pour plus d'informations, voir Procédure : projeter des résultats de requête (WCF Data Services).

Voir aussi

Concepts

Interrogation du service de données (WCF Data Services)