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
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.
Sélectionnez les propriétés suivantes à partir de l'entité
Address
:AddressLine1
,AddressLine2
,City
,StateProvince
,CountryRegion
etPostalCode
.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.
Sélectionnez
ComplexType1
dans l'Explorateur de modèles et remplacez-le parMailAddress
. 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.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.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.