Procédure pas à pas : mappage de l'héritage - TPT (table par type)

Cette rubrique montre comment implémenter l'héritage TPT (table par type) en modifiant le modèle conceptuel dans un modèle EDM (Entity Data Model). L'héritage TPT (table par type) utilise une table distincte de la base de données pour maintenir des données des propriétés non héritées et des propriétés de clé pour chaque type de la hiérarchie d'héritage. Pour plus d'informations sur l'implémentation de l'héritage avec un modèle EDM, voir Héritage (EDM).

Dans cette procédure pas à pas, vous allez implémenter l'héritage TPT (table par type) en modifiant le modèle EDM utilisé dans l'application CourseManager (pour plus d'informations, voir la section Composants requis, plus loin dans cette rubrique).

Dans l'application CourseManager, les types d'entités Course, OnlineCourse et OnsiteCourse mappent à des tables de mêmes noms. Étant donné que les types d'entités OnlineCourse et OnsiteCourse contiennent des informations qui sont spécifiques aux deux types de cours et qu'ils partagent une clé commune, ils peuvent être modifiés pour hériter du type d'entité Course. Les étapes suivantes récapitulent l'implémentation de l'héritage TPT (table par type) dans le cas présent (vous trouverez plus de détails dans les procédures fournies plus loin dans cette rubrique) :

  1. Supprimez l'association entre le type d'entité OnlineCourse et le type d'entité Course. Supprimez l'association entre le type d'entité OnsiteCourse et le type d'entité Course. Ces associations seront remplacées en implémentant la hiérarchie d'héritage.

  2. Supprimez la propriété de clé CourseID des OnlineCourse et des types d'entités OnsiteCourse. Cette propriété sera héritée du type d'entité Course.

  3. Définissez le type d'entité Course comme type de base pour les types d'entités OnlineCourse et OnsiteCourse.

  4. Transformez le type d'entité Course en type abstrait.

  5. Mappez les propriétés héritées CourseID des types d'entités OnlineCourse et OnsiteCourse aux colonnes appropriées.

Configuration requise

Pour effectuer cette procédure pas à pas, vous devez tout d'abord créer l'application CourseManager. Pour plus d'informations et d'instructions, voir le Démarrage rapide d'Entity Framework. Vous allez modifier le modèle EDM utilisé dans l'application CourseManager en implémentant l'héritage TPT (table par type). Vous étendrez ensuite les fonctionnalités de l'application pour afficher séparément des cours en ligne et sur site pour un service sélectionné.

NoteRemarque

Étant donné qu'un grand nombre des rubriques de procédure pas à pas de cette documentation utilisent l'application CourseManager comme point de départ, nous vous recommandons d'utiliser une copie de l'application CourseManager pour cette procédure pas à pas, plutôt que de modifier le code CourseManager d'origine.

La procédure pas à pas suppose que le lecteur a des compétences de base avec Visual Studio, le .NET Framework et la programmation à l'aide de Visual C# ou de Visual Basic.

Implémentation de l'héritage TPT (table par type)

Dans cette procédure, vous allez modifier la partie conceptuelle du modèle EDM SchoolModel pour implémenter l'héritage TPT (table par type).

Pour implémenter l'héritage TPT (table par type)

  1. Ouvrez la solution CourseManager dans Visual Studio.

  2. Dans l'Explorateur de solutions, double-cliquez sur le fichier School.edmx.

    Le fichier School.edmx s'ouvre dans Entity Data Model Designer (Concepteur d'entités).

  3. Cliquez avec le bouton droit sur le type d'entité OnlineCourse, puis sélectionnez Propriétés.

  4. Dans la fenêtre Propriétés, affectez la valeur Course à la propriété Type de base.

  5. Répétez les étapes 3 et 4 pour le type d'entité OnsiteCourse.

  6. Cliquez avec le bouton droit sur l'association (la ligne) entre les types d'entités OnlineCourse et Course. Sélectionnez Supprimer.

  7. Cliquez avec le bouton droit sur l'association entre les types d'entités OnsiteCourse et Course. Sélectionnez Supprimer.

  8. Cliquez avec le bouton droit sur la propriété CourseID du type d'entité OnlineCourse, puis sélectionnez Supprimer.

  9. Cliquez avec le bouton droit sur la propriété CourseID du type d'entité OnsiteCourse, puis sélectionnez Supprimer.

  10. Sélectionnez le type d'entité Course. Affectez true à sa propriété Abstrait dans la fenêtre Propriétés.

    Un message s'affiche, indiquant que la définition d'un type d'entité comme abstrait supprimera tous les mappages de fonction existants pour ce type. Cliquez sur OK.

    NoteRemarque

    Étant donné que le type d'entité Course a maintenant été transformé en type abstrait, les fonctionnalités de mise à jour de l'application CourseManager d'origine ne fonctionneront pas.

  11. Cliquez avec le bouton droit sur le type d'entité OnlineCourse, puis sélectionnez Mappage de table.

    La fenêtre Détails de Mapping s'affiche.

  12. Cliquez sur le champ Valeur/Propriété qui correspond à la colonne CourseID.

    Le champ Valeur/Propriété devient une liste déroulante des propriétés qui sont disponibles pour être mappées à la colonne correspondante.

  13. Sélectionnez CourseID dans la liste déroulante.

  14. Répétez les étapes 11 à 13 pour le type d'entité OnsiteCourse.

L'héritage TPT (table par type) est maintenant implémenté.

Création de l'interface utilisateur

Ensuite, vous allez ajouter un bouton au formulaire CourseViewer que charge et affiche le formulaire CourseDiscrimForm. Puis vous ajouterez deux contrôles DataGridView pour afficher OnsiteCourses et OnlineCourses. Enfin, vous lierez l'objet DataGridView à des contrôles BindingSource. Pour plus d'informations sur la liaison d'objets à des contrôles, voir Liaison d'objets à des contrôles (Entity Framework).

Pour créer l'interface utilisateur

  1. Cliquez avec le bouton droit sur le projet CourseManager dans l'Explorateur de solutions, pointez sur Ajouter, puis sélectionnez Nouvel élément.

    La boîte de dialogue Ajouter un nouvel élément s'affiche.

  2. Sélectionnez Windows Form, puis cliquez sur Ajouter.

    Un nouveau formulaire est ajouté au projet et s'ouvre dans le concepteur de formulaires.

  3. Dans la fenêtre Propriétés, définissez CourseDiscriminator comme nom du formulaire.

    Un nouveau formulaire est ajouté au projet et s'ouvre dans le concepteur de formulaires. Le nom du formulaire a la valeur CourseDiscriminator et le texte a la valeur CourseDiscriminator.

  4. Faites glisser un contrôle ComboBox vers le formulaire à partir de la boîte à outils, puis affectez-lui departmentList comme nom dans la fenêtre Propriétés.

  5. Faites glisser un contrôle DataGridView vers le formulaire à partir de la boîte à outils, puis affectez-lui onsiteGridView comme nom.

  6. Faites glisser un autre contrôle DataGridView de la boîte à outils vers le formulaire, puis affectez-lui onlineGridView comme nom.

  7. Dans l'Explorateur de solutions, double-cliquez sur CourseViewer.cs ou sur CourseViewer.vb.

    Le mode Création du formulaire CourseViewer apparaît.

  8. Faites glisser un contrôle Button de la boîte à outils vers le formulaire CourseViewer.

  9. Dans la fenêtre Propriétés, définissez viewDiscriminator comme nom du Button et définissez Online vs. Onsite comme texte du bouton.

  10. Double-cliquez sur l'objet ButtonviewDiscriminator.

    Le fichier code-behind du formulaire s'ouvre.

  11. Ajoutez le code suivant au gestionnaire d'événements viewDiscriminator_click :

    Dim courseDiscrim As New CourseDiscriminator
    courseDiscrim.Visible = True
    
    CourseDiscriminator courseDiscrim = new CourseDiscriminator();
    courseDiscrim.Visible = true;
    

L'interface utilisateur pour ce formulaire est maintenant terminée.

Interrogation du modèle EDM

Dans cette procédure, vous allez interroger le modèle EDM et lier les résultats à des contrôles Windows Forms.

Pour interroger le modèle EDM

  1. Ouvrez le formulaire CourseDiscriminator dans le concepteur de formulaires.

  2. Faites glisser un contrôle BindingSource de la boîte à outils vers le formulaire.

  3. Dans la fenêtre Propriétés, définissez onsiteBindingSource comme nom du BindingSource.

  4. Cliquez sur le champ en regard de la propriété Source de données dans la fenêtre Propriétés.

    Le champ devient une liste déroulante des sources de données disponibles.

  5. Cliquez sur Ajouter la source de données du projet.

    La fenêtre Choisir un type de source de données de l'Assistant Configuration de la source de données s'ouvre.

  6. Dans la zone À partir d'où l'application obtiendra-t-elle les données ?, sélectionnez Objet.

  7. Cliquez sur Suivant.

    La fenêtre Sélectionner l'objet que vous souhaitez lier s'ouvre. Le nœud supérieur d'une arborescence des ressources disponibles est affiché.

  8. Développez le nœud CourseManager, puis le nœud SchoolModel (C#) ou CourseManager.SchoolModel (Visual Basic).

  9. Sélectionnez OnsiteCourse, puis cliquez sur Terminer.

  10. Répétez les étapes 2 à 9, mais nommez le contrôle BindingSourceOnlineBindingSource et liez-le à l'objet OnlineCourse.

  11. Cliquez avec le bouton droit sur le contrôle OnsiteGridView, puis sélectionnez Propriétés.

  12. Dans la fenêtre Propriétés, cliquez sur le champ en regard de la propriété DataSource.

    Le champ devient une liste déroulante des sources de données disponibles.

  13. Sélectionnez OnsiteBindingSource.

  14. Répétez les étapes 11 à 13 pour le OnlineGridView, mais affectez OnlineBindingSource à la propriété Source de données.

    NoteRemarque

    La méthode OfType retourne une énumération à partir de laquelle un contrôle DataGridView ne peut pas générer de colonnes au moment de l'exécution. Pour afficher les informations souhaitées dans cet exemple, les sources de données des contrôles DataGridView sont définies au moment de la conception à travers des contrôles BindingSource, en fonction des classes à lier.

  15. Double-cliquez sur le formulaire CourseDiscriminator.

    Le fichier code-behind du formulaire CourseDiscriminator s'ouvre.

  16. Ajoutez les instructions using (C#) ou Imports (Visual Basic) ci-après pour faire référence au modèle créé à partir de la base de données School et à l'espace de noms de l'entité.

    Imports System.Data.Objects
    Imports System.Data.Objects.DataClasses
    
    using System.Data.Objects;
    using System.Data.Objects.DataClasses;
    
  17. Ajoutez une propriété représentant un contexte de données à la classe CourseDiscriminator :

    ' Create an ObjectContext instance based on SchoolEntity.
    Private schoolContext As SchoolEntities
    
    // Create an ObjectContext instance based on SchoolEntity.
    private SchoolEntities schoolContext;
    
  18. Dans le gestionnaire d'événements CourseDiscriminator_Load, ajoutez du code pour initialiser le contexte de l'objet et lier le contrôle departmentList à une requête qui retourne les informations relatives à Department.

    ' Initialize the ObjectContext.
    schoolContext = New SchoolEntities()
    
    ' Define a query that returns all Department objects and 
    ' related Course objects, ordered by name.
    Dim departmentQuery As ObjectQuery(Of Department) = _
            schoolContext.Department.Include("Course") _
            .OrderBy("it.Name")
    
    ' Bind the ComboBox control to the query, which is
    ' executed during data binding.
    departmentList.DataSource = departmentQuery _
    .Execute(MergeOption.OverwriteChanges)
    departmentList.DisplayMember = "Name"
    
        // Initialize the ObjectContext.
        schoolContext = new SchoolEntities();
    
        // Define a query that returns all Department objects  
        // and related Course objects, ordered by name.
        ObjectQuery<Department> departmentQuery =
            schoolContext.Department.Include("Course")
            .OrderBy("it.Name");
    
        // Bind the ComboBox control to the query, which is
        // executed during data binding.
        this.departmentList.DataSource = departmentQuery
    .Execute(MergeOption.OverwriteChanges);
        this.departmentList.DisplayMember = "Name";
    
  19. Repassez en mode concepteur du formulaire CourseDiscriminator, puis double-cliquez sur le contrôle ComboBoxdepartmentList.

    Le fichier code-behind s'ouvre. Un gestionnaire d'événements departmentList_SelectedIndexChanged a été ajouté au code.

  20. Ajoutez le code suivant au gestionnaire d'événements departmentList_SelectedIndexChanged pour mettre à jour les sources de données des contrôles BindingSource.

    ' Get the selected department object.
    Dim department As Department = CType(Me.departmentList. _
            SelectedItem, Department)
    
    ' Update the data sources for the BindingSource controls.
    onsiteBindingSource.DataSource = department.Course _
        .OfType(Of OnsiteCourse)()
    onlineBindingSource.DataSource = department.Course _
        .OfType(Of OnlineCourse)()
    
    // Get the selected department object.
    Department department = (Department)this.departmentList
        .SelectedItem;
    
    // Update the data sources for the BindingSource controls.
    onsiteBindingSource.DataSource = department.Course
        .OfType<OnsiteCourse>();
    onlineBindingSource.DataSource = department.Course
        .OfType<OnlineCourse>();
    

L'application est maintenant terminée. Appuyez sur Ctrl+F5 pour l'exécuter. Cliquez sur le bouton Onsite vs. Online pour charger le formulaire CourseDiscriminator. OnsiteCourses et OnlineCourses sont affichés dans les contrôles DataGridView pour le service sélectionné.

Liste de codes

Cette section répertorie la version finale du fichier code-behind pour le formulaire CourseDiscriminator.

Imports System.Data.Objects
Imports System.Data.Objects.DataClasses
Public Class CourseDiscriminator

    ' Create an ObjectContext instance based on SchoolEntity.
    Private schoolContext As SchoolEntities

    Private Sub CourseDiscriminator_Load(ByVal sender As System. _
        Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' Initialize the ObjectContext.
        schoolContext = New SchoolEntities()

        ' Define a query that returns all Department objects and 
        ' related Course objects, ordered by name.
        Dim departmentQuery As ObjectQuery(Of Department) = _
                schoolContext.Department.Include("Course") _
                .OrderBy("it.Name")

        ' Bind the ComboBox control to the query, which is
        ' executed during data binding.
        departmentList.DataSource = departmentQuery _
        .Execute(MergeOption.OverwriteChanges)
        departmentList.DisplayMember = "Name"
    End Sub

    Private Sub departmentList_SelectedIndexChanged(ByVal sender As  _
        System.Object, ByVal e As System.EventArgs) Handles _
        departmentList.SelectedIndexChanged
        ' Get the selected department object.
        Dim department As Department = CType(Me.departmentList. _
                SelectedItem, Department)

        ' Update the data sources for the BindingSource controls.
        onsiteBindingSource.DataSource = department.Course _
            .OfType(Of OnsiteCourse)()
        onlineBindingSource.DataSource = department.Course _
            .OfType(Of OnlineCourse)()
    End Sub
End Class
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.Objects;
using System.Data.Objects.DataClasses;

namespace CourseManager
{
    public partial class CourseDiscriminator : Form
    {
        // Create an ObjectContext instance based on SchoolEntity.
        private SchoolEntities schoolContext;

        public CourseDiscriminator()
        {
            InitializeComponent();
        }

        private void CourseDiscriminator_Load(object sender, 
            EventArgs e)
        {
            // Initialize the ObjectContext.
            schoolContext = new SchoolEntities();

            // Define a query that returns all Department objects  
            // and related Course objects, ordered by name.
            ObjectQuery<Department> departmentQuery =
                schoolContext.Department.Include("Course")
                .OrderBy("it.Name");

            // Bind the ComboBox control to the query, which is
            // executed during data binding.
            this.departmentList.DataSource = departmentQuery
        .Execute(MergeOption.OverwriteChanges);
            this.departmentList.DisplayMember = "Name";
        }

        private void departmentList_SelectedIndexChanged(object sender, 
            EventArgs e)
        {
            // Get the selected department object.
            Department department = (Department)this.departmentList
                .SelectedItem;

            // Update the data sources for the BindingSource controls.
            onsiteBindingSource.DataSource = department.Course
                .OfType<OnsiteCourse>();
            onlineBindingSource.DataSource = department.Course
                .OfType<OnlineCourse>();
        }
    }
}

Étapes suivantes

Vous avez implémenté avec succès l'héritage TPT (table par type) dans un modèle EDM. Pour plus d'informations sur la définition d'un modèle EDM avec l'héritage TPT (table par type), voir Procédure : définir un modèle avec l'héritage TPT (table par type) (Entity Framework). Pour plus d'informations sur la création d'applications qui utilisent Entity Framework, voir Guide de programmation (Entity Framework).

Voir aussi

Autres ressources

Scénarios ADO.NET Entity Data Model Designer
Tâches des outils Entity Data Model