Types complexes

La prise en charge du type complexe dans Services RIA WCF permet d'encapsuler un ensemble de propriétés d'entité au sein d'une propriété unique (complexe). Ces types permettent de simplifier une entité lorsque cette dernière contient un sous-ensemble particulier de propriétés connexes. Les types complexes peuvent également être réutilisés par une autre entité (différente) qui partage le même sous-ensemble de propriétés. Une Address, qui rassemble les propriétés d'entité requises pour spécifier une adresse, constitue un exemple courant de type complexe. L'ensemble de propriétés dans un type Address de ce genre peut inclure, par exemple, les propriétés d'entité StreetAddress, City, StateProvince, PostalCode et Country. Ce type complexe peut être utilisé à la fois par des entités Customer et Contact dès l'instant où chacune partage cet ensemble de propriétés. Une fois défini, le type Address personnalisé peut être utilisé en tant que propriété d'entité dans d'autres entités.

Un type complexe est un modèle permettant de définir des propriétés détaillées et structurées sur des types d'entité ou sur d'autres entités complexes, dans la mesure où un type complexe peut contenir des propriétés présentant également un type complexe. Un type complexe doit spécifier un nom unique au sein de l'espace de noms et contient (éventuellement) des données sous la forme d'une ou de plusieurs propriétés. Les types complexes peuvent uniquement exister en tant que propriétés sur des types d'entité ou d'autres types complexes car ils n'ont pas d'identité et, par conséquent, ne peuvent pas exister de façon indépendante. Les types complexes sont de vrais types et peuvent, à ce titre, être instanciés et utilisés dans du code, mais ils ne peuvent pas être interrogés directement ni rendus persistants dans une base de données, comme c'est le cas d'un type d'entité. Les types complexes diffèrent également des entités du fait qu'ils ne peuvent pas participer à une association. Par conséquent, il n'est pas possible de définir des propriétés de navigation sur des types complexes car elles reposent sur des types d'entité.

La prise en charge des types complexes de non-entité a été ajoutée dans les Services RIA WCF V1.0 SP1. Plus spécifiquement, cette prise en charge est fournie pour le codegen de types complexes qui dérivent de la classe de base ComplexObject. La prise en charge de la génération de proxys clients est la même que pour les entités dans Services RIA . La prise en charge des métadonnées sur les entités est également fournie, de même que la validation profonde, le suivi des modifications, les sessions de modification et la prise en charge de paramètres d'un type complexe. Cela signifie que les types personnalisés, tels qu'Address, peuvent maintenant être utilisés non seulement comme propriétés d'entité, mais également comme paramètres ou comme valeurs de retour pour les méthodes de service de domaine.

Définition et représentation d'un type complexe

Cette section décrit comment utiliser le concepteur EDM (Entity Data Model) pour encapsuler un ensemble des propriétés d'entité à partir d'un type d'entité en type complexe. Le modèle EDM (Entity Data Model) utilise un langage spécifique à un domaine (DSL), appelé CSDL (Conceptual Schema Definition Language), pour définir des modèles conceptuels. La représentation XML du type complexe est examinée dans le langage CSDL se trouvant derrière le concepteur.

Cette rubrique suppose que vous avez complété la rubrique Procédure pas à pas : Création d'une solution de Services RIA ou que vous disposez des connaissances équivalentes, ainsi que d'une solution Services RIA existante disponible.

Création d'un type complexe avec le concepteur

  1. Ouvrez la solution RIAServicesExample obtenue à partir de Procédure pas à pas : Création d'une solution de Services RIA et ouvrez le fichier AdventureWorksModel.edmx (comme c'est le cas par défaut) dans le concepteur Entity Framework Designer.

  2. Sélectionnez les propriétés suivantes à partir de l'entité Address : AddressLine1, AddressLine2, City, StateProvince, CountryRegion et PostalCode.

  3. Cliquez avec le bouton droit sur l'une d'entre elles et sélectionnez Refactoriser en nouveau type complexe. L'Explorateur de modèles s'affiche ; c'est ici où le type complexe venant d'être créé, nommé ComplexType1 par défaut, apparaît dans le dossier ComplexTypes d'AdventureWorksModel.edmx. Le nom spécifié dans l'Explorateur de modèles correspond en fait au type de la nouvelle ComplexProperty. Les sous-propriétés qui sont encapsulées par cette nouvelle propriété complexe sont désormais visibles dans l'Explorateur de modèles.

  4. Sélectionnez ComplexType1 dans l'Explorateur de modèles et remplacez-le par MailAddress. Il s'agit maintenant du type de la nouvelle ComplexProperty, ce qui peut être vérifié en sélectionnant ComplexProperty dans l'entité Address et en notant le type dans la fenêtre Propriétés.

  5. Remplacez le nom du nouveau type MailAddress par MailAddress dans la fenêtre Propriétés. Notez que ce nouveau nom s'affiche maintenant également dans le concepteur.

  6. Sélectionnez MailAddress dans le concepteur, cliquez avec le bouton droit de la souris et choisissez Mappage de table pour accéder à la table Détails de mappage. Cette table indique comment les propriétés sont mappées dans les colonnes de table de la base de données.

Représentation XML du type complexe

Les Services RIA utilisent le langage de définition de schéma conceptuel (CSDL) pour spécifier des modèles de données. Il s'agit d'un langage basé sur XML qui décrit les entités, relations et fonctions qui composent un modèle conceptuel d'une application pilotée par les données. La spécification du nouveau type MailAddress figure dans la section CSDL de XML.

Pour y accéder, sélectionnez le fichier AdventureWorksModel.edmx dans l'Explorateur de solutions, cliquez avec le bouton droit de la souris et sélectionnez Ouvrir avec, puis choisissez Éditeur XML (Texte). Visual Studio 2010 fermera le mode Design du modèle de données afin d'ouvrir la représentation XML. Par conséquent, sélectionnez Oui pour confirmer cette opération. Notez que la nouvelle propriété MailAddress est spécifiée dans l'élément <EntityType Name=”Address”> :

<Property Name="MailAddress" Type="AdventureWorksLTModel.MailAddress" Nullable="false" />

La propriété MailAddress est définie dans son propre élément sous les sections dans lesquelles sont définies les associations.

        <ComplexType Name="MailAddress">
          <Property Type="String" Name="AddressLine1" Nullable="false" MaxLength="60" FixedLength="false" Unicode="true" />
          <Property Type="String" Name="AddressLine2" MaxLength="60" FixedLength="false" Unicode="true" />
          <Property Type="String" Name="City" Nullable="false" MaxLength="30" FixedLength="false" Unicode="true" />
          <Property Type="String" Name="StateProvince" Nullable="false" MaxLength="50" FixedLength="false" Unicode="true" />
          <Property Type="String" Name="CountryRegion" Nullable="false" MaxLength="50" FixedLength="false" Unicode="true" />
          <Property Type="String" Name="PostalCode" Nullable="false" MaxLength="15" FixedLength="false" Unicode="true" />
        </ComplexType>

Notez qu'il n'existe aucun élément <Key> dans un élément <ComplexType> comme c'est le cas dans un élément <EntityType>.

Réutilisation d'un type complexe dans une autre entité

Si un type d'entité Manufacturer contenait le même ensemble de propriétés d'adresse, il serait possible de les encapsuler dans le type MailAddress complexe. Utilisez Refactoriser en nouveau type complexe comme vous l'avez fait pour créer le type complexe, puis changez le type et le nom dans la fenêtre Propriétés. Les champs désignent leurs entités respectives. Par exemple, le champ City pour MailAddress de l'entité Address est mappé à Address.City, tandis que ce champ est mappé à Manufacturer.City pour le type d'entité Manufacturer. Utilisez la table Détails de mappage pour vous assurer que les propriétés sont mappées aux colonnes correctes dans la base de données.