Partager via


Prise en main avec Entity Framework 4.0 Database First et ASP.NET 4 Web Forms - Partie 6

par Tom Dykstra

L’exemple d’application web Contoso University montre comment créer des applications ASP.NET Web Forms à l’aide d’Entity Framework 4.0 et de Visual Studio 2010. Pour plus d’informations sur la série de tutoriels, consultez le premier tutoriel de la série

Implémentation de l'héritage TPH (table par hiérarchie)

Dans le tutoriel précédent, vous avez travaillé avec des données associées en ajoutant et en supprimant des relations et en ajoutant une nouvelle entité qui avait une relation avec une entité existante. Ce didacticiel vous indiquera comment implémenter l’héritage dans le modèle de données.

Dans la programmation orientée objet, vous pouvez utiliser l’héritage pour faciliter l’utilisation des classes associées. Par exemple, vous pouvez créer Instructor des classes et Student qui dérivent d’une Person classe de base. Vous pouvez créer les mêmes types de structures d’héritage parmi les entités dans Entity Framework.

Dans cette partie du tutoriel, vous ne créerez aucune nouvelle page web. Au lieu de cela, vous allez ajouter des entités dérivées au modèle de données et modifier les pages existantes pour utiliser les nouvelles entités.

Héritage table par hiérarchie et héritage table par type

Une base de données peut stocker des informations sur les objets associés dans une table ou dans plusieurs tables. Par exemple, dans la School base de données, la Person table inclut des informations sur les étudiants et les instructeurs dans une table unique. Certaines colonnes s’appliquent uniquement aux instructeurs (HireDate), d’autres uniquement aux étudiants (EnrollmentDate) et d’autres aux deux (LastName, FirstName).

image11

Vous pouvez configurer Entity Framework pour créer Instructor des entités et Student qui héritent de l’entité Person . Ce modèle de génération d’une structure d’héritage d’entité à partir d’une table de base de données unique est appelé héritage table par hiérarchie (TPH).

Pour les cours, la School base de données utilise un modèle différent. Les cours en ligne et les cours sur site sont stockés dans des tables distinctes, chacune ayant une clé étrangère qui pointe vers la Course table. Les informations communes aux deux types de cours sont stockées uniquement dans la Course table.

image12

Vous pouvez configurer le modèle de données Entity Framework afin que OnlineCourse les entités et OnsiteCourse héritent de l’entité Course . Ce modèle de génération d’une structure d’héritage d’entité à partir de tables distinctes pour chaque type, chaque table distincte faisant référence à une table qui stocke des données communes à tous les types, est appelé héritage table par type (TPT).

Les modèles d’héritage TPH offrent généralement de meilleures performances dans Entity Framework que les modèles d’héritage TPT, car les modèles TPT peuvent entraîner des requêtes de jointure complexes. Cette procédure pas à pas montre comment implémenter l’héritage TPH. Pour ce faire, procédez comme suit :

  • Créez Instructor des types d’entités et Student qui dérivent de Person.
  • Déplacez les propriétés relatives aux entités dérivées de l’entité Person vers les entités dérivées.
  • Définissez des contraintes sur les propriétés dans les types dérivés.
  • Faites de l’entité Person une entité abstraite.
  • Mappez chaque entité dérivée à la Person table avec une condition qui spécifie comment déterminer si une Person ligne représente ce type dérivé.

Ajout d’entités d’instructeur et d’étudiant

Ouvrez le fichier SchoolModel.edmx , cliquez avec le bouton droit sur une zone non occupée dans le concepteur, sélectionnez Ajouter, puis sélectionnez Entité.

image01

Dans la boîte de dialogue Ajouter une entité , nommez l’entité Instructor et définissez son option Type de base sur Person.

image02

Cliquez sur OK. Le concepteur crée une Instructor entité qui dérive de l’entité Person . La nouvelle entité n’a pas encore de propriétés.

image03

Répétez la procédure pour créer une Student entité qui dérive également de Person.

Seuls les instructeurs ont des dates d’embauche. Vous devez donc déplacer cette propriété de l’entité Person vers l’entité Instructor . Dans l’entité Person , cliquez avec le bouton droit sur la HireDate propriété, puis cliquez sur Couper. Cliquez ensuite avec le bouton droit sur Propriétés dans l’entité Instructor , puis cliquez sur Coller.

image04

La date d’embauche d’une Instructor entité ne peut pas être null. Cliquez avec le bouton droit sur la HireDate propriété, cliquez sur Propriétés, puis, dans la fenêtre Propriétés , passez Nullable à False.

image05

Répétez la procédure pour déplacer la EnrollmentDate propriété de l’entité Person vers l’entité Student . Vérifiez que vous avez également défini sur NullableFalse pour la EnrollmentDate propriété .

Maintenant qu’une Person entité a uniquement les propriétés communes aux entités et StudentInstructor l’exception des propriétés de navigation, que vous ne déplacez pas), l’entité ne peut être utilisée que comme entité de base dans la structure d’héritage. Par conséquent, vous devez vous assurer qu’elle n’est jamais traitée comme une entité indépendante. Cliquez avec le bouton droit sur l’entité Person , sélectionnez Propriétés, puis, dans la fenêtre Propriétés , remplacez la valeur de la propriété Abstract sur True.

image06

Mappage d’entités d’instructeur et d’étudiant à la table Person

Vous devez maintenant indiquer à Entity Framework comment différencier les Instructor entités et Student dans la base de données.

Cliquez avec le bouton droit sur l’entité Instructor et sélectionnez Mappage de table. Dans la fenêtre Détails du mappage , cliquez sur Ajouter une table ou une vue , puis sélectionnez Personne.

image07

Cliquez sur Ajouter une condition, puis sélectionnez HireDate.

image09

Remplacez Opérateur par Is et Value/Property parNot Null.

image10

Répétez la procédure pour l’entité Students , en spécifiant que cette entité est mappée à la Person table lorsque la EnrollmentDate colonne n’est pas null. Enregistrez et fermez ensuite le modèle de données.

Générez le projet afin de créer les nouvelles entités en tant que classes et de les rendre disponibles dans le concepteur.

Utilisation des entités d’instructeur et d’étudiant

Lorsque vous avez créé les pages web qui fonctionnent avec les données des étudiants et des instructeurs, vous les entrez dans le Person jeu d’entités et vous avez filtré sur la HireDate propriété ou EnrollmentDate pour restreindre les données retournées aux étudiants ou aux instructeurs. Toutefois, maintenant, lorsque vous liez chaque contrôle de source de données au Person jeu d’entités, vous pouvez spécifier que seuls Student ou Instructor types d’entités doivent être sélectionnés. Comme Entity Framework sait comment différencier les étudiants et les instructeurs dans l’ensemble Person d’entités, vous pouvez supprimer les Where paramètres de propriété que vous avez entrés manuellement pour ce faire.

Dans le Designer Visual Studio, vous pouvez spécifier le type d’entité qu’un EntityDataSource contrôle doit sélectionner dans la zone déroulante EntityTypeFilter de l’AssistantConfigure Data Source, comme illustré dans l’exemple suivant.

image13

Dans la fenêtre Propriétés , vous pouvez supprimer les Where valeurs de clause qui ne sont plus nécessaires, comme illustré dans l’exemple suivant.

image14

Toutefois, étant donné que vous avez modifié le balisage des contrôles pour EntityDataSource utiliser l’attribut ContextTypeName , vous ne pouvez pas exécuter l’Assistant Configurer la source de données sur EntityDataSource les contrôles que vous avez déjà créés. Par conséquent, vous allez apporter les modifications requises en modifiant le balisage à la place.

Ouvrez la page Students.aspx . Dans le StudentsEntityDataSource contrôle, supprimez l’attribut Where et ajoutez un EntityTypeFilter="Student" attribut. Le balisage ressemblera maintenant à l’exemple suivant :

<asp:EntityDataSource ID="StudentsEntityDataSource" runat="server" 
        ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
        EntitySetName="People" EntityTypeFilter="Student"
        Include="StudentGrades"
        EnableDelete="True" EnableUpdate="True" 
        OrderBy="it.LastName" >
    </asp:EntityDataSource>

La définition de l’attribut EntityTypeFilter garantit que le EntityDataSource contrôle sélectionnera uniquement le type d’entité spécifié. Si vous souhaitez récupérer à la fois les Student types d’entité et Instructor , vous ne devez pas définir cet attribut. (Vous avez la possibilité de récupérer plusieurs types d’entités avec un seul EntityDataSource contrôle si vous utilisez le contrôle pour l’accès aux données en lecture seule. Si vous utilisez un EntityDataSource contrôle pour insérer, mettre à jour ou supprimer des entités, et si l’ensemble d’entités auquel il est lié peut contenir plusieurs types, vous ne pouvez utiliser qu’un seul type d’entité et vous devez définir cet attribut.)

Répétez la procédure pour le contrôle, à l’exception SearchEntityDataSource de supprimer uniquement la partie de l’attribut Where qui sélectionne les Student entités au lieu de supprimer la propriété. La balise d’ouverture du contrôle ressemblera maintenant à l’exemple suivant :

<asp:EntityDataSource ID="SearchEntityDataSource" runat="server" 
        ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" 
        EntitySetName="People" EntityTypeFilter="Student"
        Where="it.FirstMidName Like '%' + @StudentName + '%' or it.LastName Like '%' + @StudentName + '%'" >

Exécutez la page pour vérifier qu’elle fonctionne toujours comme avant.

image15

Mettez à jour les pages suivantes que vous avez créées dans les didacticiels précédents afin qu’elles utilisent les entités nouvelles Student et Instructor au lieu d’entités Person , puis exécutez-les pour vérifier qu’elles fonctionnent comme avant :

  • Dans StudentsAdd.aspx, ajoutez EntityTypeFilter="Student" au StudentsEntityDataSource contrôle. Le balisage ressemblera maintenant à l’exemple suivant :

    <asp:EntityDataSource ID="StudentsEntityDataSource" runat="server" 
            ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
            EntitySetName="People" EntityTypeFilter="Student"
            EnableInsert="True" 
        </asp:EntityDataSource>
    

    image16

  • Dans About.aspx, ajoutez EntityTypeFilter="Student" au StudentStatisticsEntityDataSource contrôle et supprimez Where="it.EnrollmentDate is not null". Le balisage ressemblera maintenant à l’exemple suivant :

    <asp:EntityDataSource ID="StudentStatisticsEntityDataSource" runat="server" 
            ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" 
            EntitySetName="People" EntityTypeFilter="Student"
            Select="it.EnrollmentDate, Count(it.EnrollmentDate) AS NumberOfStudents"
            OrderBy="it.EnrollmentDate" GroupBy="it.EnrollmentDate" >
        </asp:EntityDataSource>
    

    image17

  • Dans Instructors.aspx et InstructorsCourses.aspx, ajoutez EntityTypeFilter="Instructor" au InstructorsEntityDataSource contrôle et supprimez Where="it.HireDate is not null". Le balisage dans Instructors.aspx ressemble maintenant à l’exemple suivant :

    <asp:EntityDataSource ID="InstructorsEntityDataSource" runat="server" 
                ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="false"
                EntitySetName="People" EntityTypeFilter="Instructor" 
                Include="OfficeAssignment" 
                EnableUpdate="True">
            </asp:EntityDataSource>
    

    image18

    Le balisage dans InstructorsCourses.aspx ressemble désormais à l’exemple suivant :

    <asp:EntityDataSource ID="InstructorsEntityDataSource" runat="server" 
            ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" 
            EntitySetName="People" EntityTypeFilter="Instructor" 
            Select="it.LastName + ',' + it.FirstMidName AS Name, it.PersonID">
        </asp:EntityDataSource>
    

    image19

Grâce à ces modifications, vous avez amélioré la facilité de maintenance de l’application Contoso University de plusieurs façons. Vous avez déplacé la logique de sélection et de validation hors de la couche d’interface utilisateur (balisage .aspx ) et l’avez intégrée à la couche d’accès aux données. Cela permet d’isoler votre code d’application des modifications que vous pourriez apporter ultérieurement au schéma de base de données ou au modèle de données. Par exemple, vous pouvez décider que les étudiants pourraient être embauchés comme aides d’enseignants et, par conséquent, obtenir une date d’embauche. Vous pouvez ensuite ajouter une nouvelle propriété pour différencier les étudiants des instructeurs et mettre à jour le modèle de données. Aucun code dans l’application web ne doit être modifié, sauf là où vous souhaitez afficher une date d’embauche pour les étudiants. Un autre avantage de l’ajout Instructor d’entités et Student est que votre code est plus facilement compréhensible que lorsqu’il faisait référence à Person des objets qui étaient en fait des étudiants ou des instructeurs.

Vous avez maintenant vu une façon d’implémenter un modèle d’héritage dans Entity Framework. Dans le tutoriel suivant, vous allez apprendre à utiliser des procédures stockées pour mieux contrôler la façon dont Entity Framework accède à la base de données.