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
).
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.
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 etStudent
qui dérivent dePerson
. - 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 unePerson
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é.
Dans la boîte de dialogue Ajouter une entité , nommez l’entité Instructor
et définissez son option Type de base sur Person
.
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.
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.
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
.
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 Nullable
False
pour la EnrollmentDate
propriété .
Maintenant qu’une Person
entité a uniquement les propriétés communes aux entités et Student
(à Instructor
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.
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.
Cliquez sur Ajouter une condition, puis sélectionnez HireDate.
Remplacez Opérateur par Is et Value/Property parNot Null.
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.
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.
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.
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"
auStudentsEntityDataSource
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>
Dans About.aspx, ajoutez
EntityTypeFilter="Student"
auStudentStatisticsEntityDataSource
contrôle et supprimezWhere="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>
Dans Instructors.aspx et InstructorsCourses.aspx, ajoutez
EntityTypeFilter="Instructor"
auInstructorsEntityDataSource
contrôle et supprimezWhere="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>
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>
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.