Procédure : personnaliser un modèle EDM (Entity Data Model) pour travailler avec des objets personnalisés (Entity Framework)

Si vous voulez utiliser des classes de données personnalisées avec un modèle EDM (Modèle de données d'entité), les types d'entités et les propriétés définis dans le fichier CSDL (Conceptual Schema Definition Language) doivent correspondre aux classes de données personnalisées. Les outils Entity Framework génèrent un ensemble de mappage dans lequel les types d'entités et les jeux d'entités du fichier CSDL correspondent aux tables de la base de données. Le processus de mise à jour de ces fichiers de mappage pour les classes de données personnalisées est le suivant :

  1. Mettez à jour le fichier CSDL pour qu'il corresponde aux classes de données personnalisées.

  2. Mettez à jour le mappage dans le fichier MSL (Mapping Specification Language).

  3. Mettez à jour le fichier SSDL (Store Schema Definition Language), si nécessaire.

  4. Validez les fichiers de mappage mis à jour.

  5. Arrêtez la génération de la couche objet par Visual Studio.

Pour exécuter l'exemple de cette rubrique, vous devez avoir déjà utilisé l'utilitaire EDM Generator (EdmGen.exe) ou l'Assistant EDM pour générer les fichiers de mappage EDM. Pour plus d'informations, voir Procédure : utiliser EdmGen.exe pour générer un modèle EDM (Entity Framework). Si vous utilisez Entity Data Model Designer dans Visual Studio, vous devez également désactiver la génération de la couche objet basée sur le fichier CSDL mis à jour. Sinon, votre projet contiendra des classes de données en double.

Pour mettre à jour le fichier CSDL afin qu'il reflète les objets de données personnalisés.

  1. Ouvrez le fichier CSDL dans Visual Studio ou dans le Bloc-notes (notepad.exe).

  2. Renommez les éléments EntityType et EntitySet pour refléter les noms des classes de données personnalisées.

  3. Supprimez les éléments EntityType et EntitySet pour toutes les entités qui n'ont pas de classe de données personnalisée correspondante.

  4. Renommez les éléments Property de chaque type pour qu'ils correspondent au nom des propriétés de la classe de données personnalisée.

  5. Supprimez les éléments Property pour toutes les propriétés qui n'existent pas dans la classe de données personnalisée.

  6. Enregistrez les modifications apportées au fichier CSDL.

Pour mettre à jour le fichier MSL afin de mapper les objets de données personnalisés aux objets de la source de données

  1. Ouvrez le fichier MSL dans Visual Studio ou dans le Bloc-notes (notepad.exe).

  2. Renommez l'élément EntitySetMapping et l'attribut TypeName pour refléter les noms des classes de données personnalisées.

  3. Supprimez l'élément EntitySetMapping pour toutes les entités qui n'ont pas de classe de données personnalisée correspondante.

  4. Renommez les éléments ScalarProperty de chaque type pour qu'ils correspondent aux noms des propriétés de la classe de données personnalisée.

  5. Supprimez l'élément ScalarProperty pour toutes les propriétés qui n'existent pas dans la classe de données personnalisée.

  6. Renommez l'élément EndProperty d'AssociationSetMapping pour refléter les noms des classes de données personnalisées.

  7. Renommez les éléments ScalarProperty de chaque AssociationSetMapping pour qu'ils correspondent aux noms des propriétés de la classe de données personnalisée.

    NoteRemarque

    Ne modifiez aucune des propriétés ColumnName.

  8. Supprimez l'élément AssociationSetMapping pour les associations entre toutes les entités qui n'existent pas dans les classes de données personnalisées.

  9. Enregistrez les modifications apportées au fichier MSL.

Pour mettre à jour le fichier SSDL afin de supprimer les entités qui n'existent pas dans les classes de données personnalisées

  1. Ouvrez le fichier SSDL dans Visual Studio ou dans le Bloc-notes (notepad.exe).

  2. Supprimez les éléments EntityType pour toutes les entités qui ne sont pas mappées aux classes de données personnalisées.

  3. Supprimez les éléments ScalarProperty pour toutes les propriétés qui ne sont pas mappées aux propriétés des classes de données personnalisées.

  4. Enregistrez les modifications apportées au fichier SSDL.

Pour valider les fichiers de mappage mis à jour

  1. Exécutez l'utilitaire EdmGen.exe dans le répertoire qui contient les fichiers de mappage. Utilisez la commande suivante :

    %windir%\Microsoft.NET\Framework\v3.5\edmgen.exe /mode:ValidateArtifacts  
    /inssdl:.\YourModel.ssdl /inmsl:.\YourModel.msl /incsdl:.\YourModel.csdl 
    
    NoteRemarque

    Supprimez les sauts de ligne et remplacez YourModel par le nom utilisé pour vos fichiers de mappage.

  2. Vérifiez la sortie et réparez toutes les erreurs de validation.

Pour régénérer, enregistrer et supprimer le code objet généré automatiquement

  1. Dans l'Explorateur de solutions de Visual Studio, cliquez avec le bouton droit sur le fichier* *CSDL, puis sélectionnez Exécuter un outil personnalisé.

    Cette opération régénère la couche objet sur la base du fichier CSDL modifié.

  2. Développez le nœud de fichier CSDL, ouvrez le fichier de concepteur, puis enregistrez le fichier sous un autre nom.

    Cette opération enregistre le fichier de couche objet généré automatiquement. Le code contenu dans ce fichier est utilisé dans la rubrique Procédure : utiliser Object Services avec des objets personnalisés (Entity Framework).

  3. Excluez le fichier de concepteur du projet.

  4. Sélectionnez le fichier CSDL et effacez la valeur Outil personnalisé dans la fenêtre Propriétés.

    Cela empêchera la régénération du fichier de couche objet. Pour générer ce fichier à l'avenir, tapez EntityModelCodeGenerator pour Outil personnalisé dans la fenêtre Propriétés, puis répétez l'étape 1.

Exemple

Le fichier CSDL suivant a été personnalisé pour prendre en charge les classes de données personnalisées Orders et LineItem.

<Schema Namespace="Microsoft.Samples.Edm" Alias="Self" xmlns="https://schemas.microsoft.com/ado/2006/04/edm">
  <EntityContainer Name="SalesOrdersEntities">
    <EntitySet Name="LineItem" EntityType="Microsoft.Samples.Edm.LineItem" />
    <EntitySet Name="Order" EntityType="Microsoft.Samples.Edm.Order" />
    <AssociationSet Name="FK_LineItem_Order_OrderId" Association="Microsoft.Samples.Edm.FK_LineItem_Order_OrderId">
      <End Role="Order" EntitySet="Order" />
      <End Role="LineItem" EntitySet="LineItem" />
    </AssociationSet>
  </EntityContainer>
  <EntityType Name="LineItem">
    <Key>
      <PropertyRef Name="LineItemId" />
    </Key>
    <Property Name="LineItemId" Type="Int32" Nullable="false" />
    <Property Name="TrackingNumber" Type="String" MaxLength="25" />
    <Property Name="Quantity" Type="Int16" Nullable="false" />
    <Property Name="Product" Type="Int32" Nullable="false" />
    <Property Name="Price" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
    <Property Name="Discount" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
    <NavigationProperty Name="Order" Relationship="Microsoft.Samples.Edm.FK_LineItem_Order_OrderId" 
                        FromRole="LineItem" ToRole="Order" />
  </EntityType>
  <EntityType Name="Order">
    <Key>
      <PropertyRef Name="OrderId" />
    </Key>
    <Property Name="OrderId" Type="Int32" Nullable="false" />
    <Property Name="OrderDate" Type="DateTime" Nullable="false" />
    <Property Name="DueDate" Type="DateTime" Nullable="false" />
    <Property Name="ShipDate" Type="DateTime" />
    <Property Name="Status" Type="Byte" Nullable="false" />
    <Property Name="Customer" Type="Int32" Nullable="false" />
    <Property Name="SubTotal" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
    <Property Name="TaxAmt" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
    <Property Name="Freight" Type="Decimal" Nullable="false" Precision="19" Scale="4" />
    <Property Name="ExtendedInfo" Type="Self.OrderInfo" Nullable="false" />
    <NavigationProperty Name="LineItem" Relationship="Microsoft.Samples.Edm.FK_LineItem_Order_OrderId" 
                        FromRole="Order" ToRole="LineItem" />
  </EntityType>
    <ComplexType Name="OrderInfo">
        <Property Name="OrderNumber" Type="String" Nullable="false" MaxLength="25" />
        <Property Name="PurchaseOrder" Type="String" MaxLength="25" />
        <Property Name="AccountNumber" Type="String" MaxLength="15" />
        <Property Name="Comment" Type="String" MaxLength="128" />
    </ComplexType>
  <Association Name="FK_LineItem_Order_OrderId">
    <End Role="Order" Type="Microsoft.Samples.Edm.Order" Multiplicity="1" />
    <End Role="LineItem" Type="Microsoft.Samples.Edm.LineItem" Multiplicity="*" />
  </Association>
</Schema>

Le fichier MSL suivant a été personnalisé pour mapper les classes de données personnalisées Orders et LineItem aux tables SalesOrderHeader et SalesOrderDetail de la base de données AdventureWorks.

<Mapping Space="C-S" xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS">
  <EntityContainerMapping StorageEntityContainer="Sales" CdmEntityContainer="SalesOrdersEntities">
    <EntitySetMapping Name="LineItem" StoreEntitySet="SalesOrderDetail" TypeName="Microsoft.Samples.Edm.LineItem">
      <ScalarProperty Name="LineItemId" ColumnName="SalesOrderDetailID" />
      <ScalarProperty Name="TrackingNumber" ColumnName="CarrierTrackingNumber" />
      <ScalarProperty Name="Quantity" ColumnName="OrderQty" />
      <ScalarProperty Name="Product" ColumnName="ProductID" />
      <ScalarProperty Name="Price" ColumnName="UnitPrice" />
      <ScalarProperty Name="Discount" ColumnName="UnitPriceDiscount" />
    </EntitySetMapping>
    <EntitySetMapping Name="Order" StoreEntitySet="SalesOrderHeader" TypeName="Microsoft.Samples.Edm.Order">
      <ScalarProperty Name="OrderId" ColumnName="SalesOrderID" />
      <ScalarProperty Name="OrderDate" ColumnName="OrderDate" />
      <ScalarProperty Name="DueDate" ColumnName="DueDate" />
      <ScalarProperty Name="ShipDate" ColumnName="ShipDate" />
      <ScalarProperty Name="Status" ColumnName="Status" />
      <ScalarProperty Name="Customer" ColumnName="CustomerID" />
      <ScalarProperty Name="SubTotal" ColumnName="SubTotal" />
      <ScalarProperty Name="TaxAmt" ColumnName="TaxAmt" />
      <ScalarProperty Name="Freight" ColumnName="Freight" />
      <ComplexProperty Name ="ExtendedInfo" TypeName ="Microsoft.Samples.Edm.OrderInfo">
        <ScalarProperty Name="OrderNumber" ColumnName="SalesOrderNumber" />
        <ScalarProperty Name="PurchaseOrder" ColumnName="PurchaseOrderNumber" />
        <ScalarProperty Name="AccountNumber" ColumnName="AccountNumber" />
        <ScalarProperty Name="Comment" ColumnName="Comment" />
      </ComplexProperty>
    </EntitySetMapping>
    <AssociationSetMapping Name="FK_LineItem_Order_OrderId" TypeName="Microsoft.Samples.Edm.FK_LineItem_Order_OrderId" StoreEntitySet="SalesOrderDetail">
      <EndProperty Name="Order">
        <ScalarProperty Name="OrderId" ColumnName="SalesOrderID" />
      </EndProperty>
      <EndProperty Name="LineItem">
        <ScalarProperty Name="LineItemId" ColumnName="SalesOrderDetailID" />
      </EndProperty>
      <Condition ColumnName="SalesOrderID" IsNull="false" />
    </AssociationSetMapping>
  </EntityContainerMapping>
</Mapping>

Le fichier SSDL suivant a été personnalisé pour prendre en charge les classes de données personnalisées Orders et LineItem en utilisant les tables SalesOrderHeader et SalesOrderDetail de la base de données AdventureWorks.

<Schema Namespace="Microsoft.Samples.Edm.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2005" xmlns="https://schemas.microsoft.com/ado/2006/04/edm/ssdl">
  <EntityContainer Name="Sales">
    <EntitySet Name="SalesOrderDetail" EntityType="Microsoft.Samples.Edm.Store.SalesOrderDetail" />
    <EntitySet Name="SalesOrderHeader" EntityType="Microsoft.Samples.Edm.Store.SalesOrderHeader" />
    <AssociationSet Name="FK_LineItem_Orders_OrderId" Association="Microsoft.Samples.Edm.Store.FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID">
      <End Role="SalesOrderHeader" EntitySet="SalesOrderHeader" />
      <End Role="SalesOrderDetail" EntitySet="SalesOrderDetail" />
    </AssociationSet>
  </EntityContainer>
  <EntityType Name="SalesOrderDetail">
    <Key>
      <PropertyRef Name="SalesOrderDetailID" />
    </Key>
    <Property Name="SalesOrderID" Type="int" Nullable="false" />
    <Property Name="SalesOrderDetailID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
    <Property Name="CarrierTrackingNumber" Type="nvarchar" MaxLength="25" />
    <Property Name="OrderQty" Type="smallint" Nullable="false" />
    <Property Name="ProductID" Type="int" Nullable="false" />
    <Property Name="UnitPrice" Type="money" Nullable="false" />
    <Property Name="UnitPriceDiscount" Type="money" Nullable="false" />
  </EntityType>
  <EntityType Name="SalesOrderHeader">
    <Key>
      <PropertyRef Name="SalesOrderID" />
    </Key>
    <Property Name="SalesOrderID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
    <Property Name="OrderDate" Type="datetime" Nullable="false" />
    <Property Name="DueDate" Type="datetime" Nullable="false" />
    <Property Name="ShipDate" Type="datetime" />
    <Property Name="Status" Type="tinyint" Nullable="false" />
    <Property Name="SalesOrderNumber" Type="nvarchar" Nullable="false" StoreGeneratedPattern="Computed" MaxLength="25" />
    <Property Name="PurchaseOrderNumber" Type="nvarchar" MaxLength="25" />
    <Property Name="AccountNumber" Type="nvarchar" MaxLength="15" />
    <Property Name="CustomerID" Type="int" Nullable="false" />
    <Property Name="SubTotal" Type="money" Nullable="false" />
    <Property Name="TaxAmt" Type="money" Nullable="false" />
    <Property Name="Freight" Type="money" Nullable="false" />
    <Property Name="Comment" Type="nvarchar" MaxLength="128" />
  </EntityType>
  <Association Name="FK_SalesOrderDetail_SalesOrderHeader_SalesOrderID">
    <End Role="SalesOrderHeader" Type="Microsoft.Samples.Edm.Store.SalesOrderHeader" Multiplicity="1" />
    <End Role="SalesOrderDetail" Type="Microsoft.Samples.Edm.Store.SalesOrderDetail" Multiplicity="*" />
    <ReferentialConstraint>
      <Principal Role="SalesOrderHeader">
        <PropertyRef Name="SalesOrderID" />
      </Principal>
      <Dependent Role="SalesOrderDetail">
        <PropertyRef Name="SalesOrderID" />
      </Dependent>
    </ReferentialConstraint>
  </Association>
</Schema>

Voir aussi

Concepts

Personnalisation des objets (Entity Framework)

Autres ressources

Schémas et spécification de mappage (Entity Framework)
Utilisation d'objets personnalisés (Tâches Entity Framework)