Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
par Tom Dykstra
L’exemple d’application web Contoso University montre comment créer ASP.NET applications 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 didacticiel de la série
Contrôle EntityDataSource
Dans le tutoriel précédent, vous avez créé un site web, une base de données et un modèle de données. Dans ce tutoriel, vous travaillez avec le EntityDataSource contrôle fourni par ASP.NET afin de faciliter l’utilisation d’un modèle de données Entity Framework. Vous allez créer un GridView contrôle pour l’affichage et la modification des données des étudiants, un DetailsView contrôle pour l’ajout de nouveaux étudiants et un DropDownList contrôle permettant de sélectionner un service (que vous utiliserez ultérieurement pour afficher les cours associés).
Notez que dans cette application, vous n’ajouterez pas de validation d’entrée aux pages qui mettent à jour la base de données, et certaines des gestions des erreurs ne seront pas aussi robustes que nécessaire dans une application de production. Cela permet au didacticiel de se concentrer sur Entity Framework et de ne pas être trop long. Pour plus d’informations sur l’ajout de ces fonctionnalités à votre application, consultez Validation de l’entrée utilisateur dans ASP.NET pages web et gestion des erreurs dans ASP.NET Pages et applications.
Ajout et configuration du contrôle EntityDataSource
Vous allez commencer par configurer un EntityDataSource contrôle pour lire Person des entités à partir de l’ensemble People d’entités.
Vérifiez que Visual Studio est ouvert et que vous travaillez avec le projet que vous avez créé dans la partie 1. Si vous n’avez pas créé le projet depuis que vous avez créé le modèle de données ou depuis la dernière modification que vous y avez apportée, générez le projet maintenant. Les modifications apportées au modèle de données ne sont pas mises à la disposition du concepteur tant que le projet n’est pas généré.
Créez une page web à l’aide du formulaire web à l’aide du modèle page maître et nommez-la Students.aspx.
Spécifiez Site.Master comme page maître. Toutes les pages que vous créez pour ces didacticiels utilisent cette page maître.
En mode Source , ajoutez un h2 titre au Content contrôle nommé Content2, comme illustré dans l’exemple suivant :
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Student List</h2>
</asp:Content>
Sous l’onglet Données de la boîte à outils, faites glisser un EntityDataSource contrôle vers la page, déposez-le sous le titre et remplacez l’ID par :StudentsEntityDataSource
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Student List</h2>
<asp:EntityDataSource ID="StudentsEntityDataSource" runat="server">
</asp:EntityDataSource>
</asp:Content>
Basculez vers l’affichage Création , cliquez sur la balise active du contrôle de source de données, puis cliquez sur Configurer la source de données pour lancer l’Assistant Configurer la source de données .
Dans l’étape Configurer ObjectContext , sélectionnez SchoolEntities comme valeur de connexion nommée, puis SchoolEntities comme valeur DefaultContainerName . Cliquez ensuite sur Suivant.
Remarque : Si vous obtenez la boîte de dialogue suivante à ce stade, vous devez générer le projet avant de continuer.
Dans l’étape Configurer la sélection des données , sélectionnez Contacts comme valeur pour EntitySetName. Sous Sélectionner, vérifiez que la case à cocher Sélectionner A est cochée. Sélectionnez ensuite les options permettant d’activer la mise à jour et la suppression. Lorsque vous avez terminé, cliquez sur Terminer.
Configuration des règles de base de données pour autoriser la suppression
Vous allez créer une page qui permet aux utilisateurs de supprimer les étudiants de la Person table, qui a trois relations avec d’autres tables (Course, StudentGradeet OfficeAssignment). Par défaut, la base de données vous empêche de supprimer une ligne s’il Person existe des lignes associées dans l’une des autres tables. Vous pouvez d’abord supprimer manuellement les lignes associées, ou vous pouvez configurer la base de données pour les supprimer automatiquement lorsque vous supprimez une Person ligne. Pour les enregistrements des étudiants dans ce didacticiel, vous allez configurer la base de données pour supprimer automatiquement les données associées. Étant donné que les étudiants peuvent avoir des lignes associées uniquement dans la StudentGrade table, vous devez configurer l’une des trois relations.
Si vous utilisez le fichier School.mdf que vous avez téléchargé à partir du projet qui suit ce didacticiel, vous pouvez ignorer cette section, car ces modifications de configuration ont déjà été effectuées. Si vous avez créé la base de données en exécutant un script, configurez la base de données en effectuant les procédures suivantes.
Dans l’Explorateur de serveurs, ouvrez le diagramme de base de données que vous avez créé dans la partie 1. Cliquez avec le bouton droit sur la relation entre Person et StudentGrade (la ligne entre les tables), puis sélectionnez Propriétés.
Dans la fenêtre Propriétés , développez INSERT et UPDATE Specification et définissez la propriété DeleteRule sur Cascade.
Enregistrez et fermez le diagramme. Si vous êtes invité à mettre à jour la base de données, cliquez sur Oui.
Pour vous assurer que le modèle conserve les entités en mémoire synchronisées avec ce que fait la base de données, vous devez définir des règles correspondantes dans le modèle de données. Ouvrez SchoolModel.edmx, cliquez avec le bouton droit sur la ligne d’association entre Person et StudentGrade, puis sélectionnez Propriétés.
Dans la fenêtre Propriétés, définissez End1 OnDelete sur Cascade.
Enregistrez et fermez le fichier SchoolModel.edmx, puis régénérez le projet.
En général, lorsque la base de données change, vous avez plusieurs choix pour synchroniser le modèle :
- Pour certains types de modifications (telles que l’ajout ou l’actualisation de tables, de vues ou de procédures stockées), cliquez avec le bouton droit dans le concepteur et sélectionnez Mettre à jour le modèle à partir de la base de données pour que le concepteur apporte automatiquement les modifications.
- Régénérer le modèle de données.
- Effectuez des mises à jour manuelles comme celle-ci.
Dans ce cas, vous pourriez avoir régénéré le modèle ou actualisé les tables affectées par la modification de la relation, mais vous devrez à nouveau modifier le nom du champ (de à FirstName).FirstMidName
Utilisation d’un contrôle GridView pour lire et mettre à jour des entités
Dans cette section, vous allez utiliser un GridView contrôle pour afficher, mettre à jour ou supprimer des étudiants.
Ouvrez ou basculez vers Students.aspx et basculez vers l’affichage Design. Sous l’onglet Données de la boîte à outils, faites glisser un GridView contrôle à droite du EntityDataSource contrôle, nommez-le StudentsGridView, cliquez sur la balise active, puis sélectionnez StudentsEntityDataSource comme source de données.
Cliquez sur Actualiser le schéma (cliquez sur Oui si vous êtes invité à confirmer), puis sur Activer la pagination, Activer le tri, Activer la modification et Activer la suppression.
Cliquez sur Modifier les colonnes.
Dans la zone Champs Sélectionnés , supprimez PersonID, LastName et HireDate. En règle générale, vous n’affichez pas de clé d’enregistrement pour les utilisateurs, la date d’embauche n’est pas pertinente pour les étudiants. Vous devez donc placer les deux parties du nom dans un champ. Vous n’avez donc besoin que d’un des champs de nom.)
Sélectionnez le champ FirstMidName , puis cliquez sur Convertir ce champ en un TemplateField.
Procédez de la même façon pour EnrollmentDate.
Cliquez sur OK , puis basculez vers la vue Source . Les modifications restantes seront plus faciles à effectuer directement dans le balisage. Le balisage de contrôle GridView ressemble maintenant à l’exemple suivant.
<asp:GridView ID="StudentsGridView" runat="server" AllowPaging="True"
AllowSorting="True" AutoGenerateColumns="False" DataKeyNames="PersonID"
DataSourceID="StudentsEntityDataSource">
<Columns>
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
<asp:TemplateField HeaderText="FirstMidName" SortExpression="FirstMidName">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("FirstMidName") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("FirstMidName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="EnrollmentDate" SortExpression="EnrollmentDate">
<EditItemTemplate>
<asp:TextBox ID="TextBox2" runat="server" Text='<%# Bind("EnrollmentDate") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Bind("EnrollmentDate") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
La première colonne après le champ de commande est un champ de modèle qui affiche actuellement le prénom. Modifiez le balisage de ce champ de modèle pour ressembler à l’exemple suivant :
<asp:TemplateField HeaderText="Name" SortExpression="LastName">
<EditItemTemplate>
<asp:TextBox ID="LastNameTextBox" runat="server" Text='<%# Bind("LastName") %>'></asp:TextBox>
<asp:TextBox ID="FirstNameTextBox" runat="server" Text='<%# Bind("FirstMidName") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="LastNameLabel" runat="server" Text='<%# Eval("LastName") %>'></asp:Label>,
<asp:Label ID="FirstNameLabel" runat="server" Text='<%# Eval("FirstMidName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
En mode d’affichage, deux Label éléments de contrôle affichent le nom et le prénom. En mode Édition, deux zones de texte sont fournies pour que vous puissiez modifier le prénom et le nom. Tout comme avec les Label contrôles en mode d’affichage, vous utilisez Bind et Eval avec des contrôles de source de données ASP.NET qui se connectent directement aux bases de données. La seule différence est que vous spécifiez des propriétés d’entité au lieu de colonnes de base de données.
La dernière colonne est un champ de modèle qui affiche la date d’inscription. Modifiez le balisage de ce champ pour qu’il ressemble à l’exemple suivant :
<asp:TemplateField HeaderText="Enrollment Date" SortExpression="EnrollmentDate">
<EditItemTemplate>
<asp:TextBox ID="EnrollmentDateTextBox" runat="server" Text='<%# Bind("EnrollmentDate", "{0:d}") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="EnrollmentDateLabel" runat="server" Text='<%# Eval("EnrollmentDate", "{0:d}") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
En mode d’affichage et d’édition, la chaîne de format « {0,d} » entraîne l’affichage de la date au format « date courte ». (Votre ordinateur peut être configuré pour afficher ce format différemment des images d’écran affichées dans ce didacticiel.)
Notez que dans chacun de ces champs de modèle, le concepteur a utilisé une Bind expression par défaut, mais vous l’avez changé en expression Eval dans les ItemTemplate éléments. L’expression Bind rend les données disponibles dans GridView les propriétés de contrôle si vous devez accéder aux données dans le code. Dans cette page, vous n’avez pas besoin d’accéder à ces données dans le code, ce qui vous permet d’utiliser Eval, ce qui est plus efficace. Pour plus d’informations, consultez Obtenir vos données hors des contrôles de données.
Révision du balisage de contrôle EntityDataSource pour améliorer les performances
Dans le balisage du contrôle EntityDataSource, supprimez les attributs ConnectionString et DefaultContainerName et remplacez-les par un attribut ContextTypeName="ContosoUniversity.DAL.SchoolEntities". Il s’agit d’une modification que vous devez apporter chaque fois que vous créez un EntityDataSource contrôle, sauf si vous devez utiliser une connexion différente de celle codée en dur dans la classe de contexte d’objet. L’utilisation de l’attribut ContextTypeName offre les avantages suivants :
- Meilleures performances. Lorsque le
EntityDataSourcecontrôle initialise le modèle de données à l’aide des attributsConnectionStringetDefaultContainerName, il effectue un travail supplémentaire pour charger des métadonnées à chaque requête. Cela n’est pas nécessaire si vous spécifiez l’attributContextTypeName. - Le chargement différé est activé par défaut dans les classes de contexte d’objet générées (comme
SchoolEntitiesdans ce didacticiel) dans Entity Framework 4.0. Cela signifie que les propriétés de navigation sont chargées automatiquement avec des données associées lorsque vous en avez besoin. Le chargement différé est expliqué plus en détail plus loin dans ce tutoriel. - Toutes les personnalisations que vous avez appliquées à la classe de contexte d’objet (dans ce cas, la
SchoolEntitiesclasse) sont disponibles pour les contrôles qui utilisent leEntityDataSourcecontrôle. La personnalisation de la classe de contexte d’objet est une rubrique avancée qui n’est pas abordée dans cette série de tutoriels. Pour plus d’informations, consultez Extension des types générés par Entity Framework.
Le balisage ressemble désormais à l’exemple suivant (l’ordre des propriétés peut être différent) :
<asp:EntityDataSource ID="StudentsEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
EntitySetName="People"
EnableDelete="True" EnableUpdate="True">
</asp:EntityDataSource>
L’attribut EnableFlattening fait référence à une fonctionnalité nécessaire dans les versions antérieures d’Entity Framework, car les colonnes de clé étrangère n’ont pas été exposées en tant que propriétés d’entité. La version actuelle permet d’utiliser des associations de clés étrangères, ce qui signifie que les propriétés de clé étrangère sont exposées pour toutes les associations sauf les associations de plusieurs à plusieurs. Si vos entités ont des propriétés de clé étrangère et aucun type complexe, vous pouvez laisser cet attribut défini sur False. Ne supprimez pas l’attribut du balisage, car la valeur par défaut est True. Pour plus d’informations, consultez Flattening Objects (EntityDataSource).
Exécutez la page et vous voyez une liste d’étudiants et d’employés (vous allez filtrer uniquement les étudiants dans le tutoriel suivant). Le prénom et le nom sont affichés ensemble.
Pour trier l’affichage, cliquez sur un nom de colonne.
Cliquez sur Modifier dans n’importe quelle ligne. Les zones de texte s’affichent dans lesquelles vous pouvez modifier le prénom et le nom.
Le bouton Supprimer fonctionne également. Cliquez sur Supprimer pour une ligne qui a une date d’inscription et la ligne disparaît. (Les lignes sans date d’inscription représentent des instructeurs et vous pouvez obtenir une erreur d’intégrité référentielle. Dans le tutoriel suivant, vous allez filtrer cette liste pour inclure uniquement les étudiants.)
Affichage de données à partir d’une propriété de navigation
Supposons maintenant que vous souhaitez savoir combien de cours chaque étudiant est inscrit. Entity Framework fournit ces informations dans la StudentGrades propriété de navigation de l’entité Person . Étant donné que la conception de la base de données ne permet pas à un étudiant d’être inscrit dans un cours sans avoir reçu une note, pour ce didacticiel, vous pouvez supposer que la présence d’une ligne dans la StudentGrade ligne de table associée à un cours est identique à celle qui est inscrite dans le cours. (La Courses propriété de navigation est uniquement destinée aux instructeurs.)
Lorsque vous utilisez l’attribut ContextTypeName du EntityDataSource contrôle, Entity Framework récupère automatiquement des informations pour une propriété de navigation lorsque vous accédez à cette propriété. Il s’agit du chargement différé. Toutefois, cela peut être inefficace, car il entraîne un appel distinct à la base de données chaque fois que des informations supplémentaires sont nécessaires. Si vous avez besoin de données de la propriété de navigation pour chaque entité retournée par le EntityDataSource contrôle, il est plus efficace de récupérer les données associées ainsi que l’entité elle-même dans un seul appel à la base de données. Il s’agit du chargement hâtif et vous spécifiez le chargement hâtif pour une propriété de navigation en définissant la Include propriété du EntityDataSource contrôle.
Dans Students.aspx, vous souhaitez afficher le nombre de cours par étudiant, donc le chargement hâtif est le meilleur choix. Si vous affichiez tous les étudiants, mais montrant le nombre de cours uniquement pour quelques-uns d’entre eux (ce qui nécessiterait l’écriture d’un code en plus du balisage), le chargement différé peut être un meilleur choix.
Ouvrez ou basculez vers Students.aspx, basculez vers l’affichage Création , sélectionnez StudentsEntityDataSourceet, dans la fenêtre Propriétés , définissez la propriété Include sur StudentGrades. (Si vous souhaitez obtenir plusieurs propriétés de navigation, vous pouvez spécifier leurs noms séparés par des virgules , par exemple , StudentGrades, Courses.)
Basculez vers la vue Source . Dans le StudentsGridView contrôle, après le dernier asp:TemplateField élément, ajoutez le nouveau champ de modèle suivant :
<asp:TemplateField HeaderText="Number of Courses">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("StudentGrades.Count") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
Dans l’expression Eval , vous pouvez référencer la propriété StudentGradesde navigation . Étant donné que cette propriété contient une collection, elle a une Count propriété que vous pouvez utiliser pour afficher le nombre de cours dans lesquels l’étudiant est inscrit. Dans un didacticiel ultérieur, vous allez découvrir comment afficher des données à partir des propriétés de navigation qui contiennent des entités uniques au lieu de collections. (Notez que vous ne pouvez pas utiliser d’éléments BoundField pour afficher les données des propriétés de navigation.)
Exécutez la page et vous voyez maintenant combien de cours chaque étudiant est inscrit.
Utilisation d’un contrôle DetailsView pour insérer des entités
L’étape suivante consiste à créer une page qui a un DetailsView contrôle qui vous permettra d’ajouter de nouveaux étudiants. Fermez le navigateur, puis créez une page web à l’aide de la page maître Site.Master . Nommez la page StudentsAdd.aspx, puis basculez vers la vue Source .
Ajoutez le balisage suivant pour remplacer le balisage existant pour le Content contrôle nommé Content2:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Add New Students</h2>
<asp:EntityDataSource ID="StudentsEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False"
EnableInsert="True" EntitySetName="People">
</asp:EntityDataSource>
<asp:DetailsView ID="StudentsDetailsView" runat="server"
DataSourceID="StudentsEntityDataSource" AutoGenerateRows="False"
DefaultMode="Insert">
<Fields>
<asp:BoundField DataField="FirstMidName" HeaderText="First Name"
SortExpression="FirstMidName" />
<asp:BoundField DataField="LastName" HeaderText="Last Name"
SortExpression="LastName" />
<asp:BoundField DataField="EnrollmentDate" HeaderText="Enrollment Date"
SortExpression="EnrollmentDate" />
<asp:CommandField ShowInsertButton="True" />
</Fields>
</asp:DetailsView>
</asp:Content>
Ce balisage crée un EntityDataSource contrôle similaire à celui que vous avez créé dans Students.aspx, sauf qu’il active l’insertion. Comme avec le GridView contrôle, les champs liés du DetailsView contrôle sont codés exactement comme ils le feraient pour un contrôle de données qui se connecte directement à une base de données, sauf qu’ils référencent les propriétés d’entité. Dans ce cas, le DetailsView contrôle est utilisé uniquement pour l’insertion de lignes. Vous avez donc défini le mode Insertpar défaut sur .
Exécutez la page et ajoutez un nouvel étudiant.
Rien ne se passera après l’insertion d’un nouvel étudiant, mais si vous exécutez maintenant Students.aspx, vous verrez les nouvelles informations sur l’étudiant.
Affichage des données dans une liste déroulante
Dans les étapes suivantes, vous allez lier un contrôle à un DropDownList jeu d’entités à l’aide d’un EntityDataSource contrôle. Dans cette partie du tutoriel, vous ne ferez pas grand-chose avec cette liste. Dans les parties suivantes, toutefois, vous allez utiliser la liste pour permettre aux utilisateurs de sélectionner un service pour afficher les cours associés au service.
Créez une page web nommée Courses.aspx. En mode Source , ajoutez un titre au Content contrôle nommé Content2:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Courses by Department</h2>
</asp:Content>
En mode Création, ajoutez un EntityDataSource contrôle à la page comme vous l’avez fait précédemment, en le nommant cette fois DepartmentsEntityDataSource. Sélectionnez Services comme valeur EntitySetName , puis sélectionnez uniquement les propriétés DepartmentID et Name .
Sous l’onglet Standard de la boîte à outils, faites glisser un DropDownList contrôle vers la page, nommez-le DepartmentsDropDownList, cliquez sur la balise active, puis sélectionnez Choisir une source de données pour démarrer l’Assistant Configuration de la source de données.
Dans l’étape Choisir une source de données , sélectionnez DepartmentEntityDataSource comme source de données, cliquez sur Actualiser le schéma, puis sélectionnez Nom comme champ de données à afficher et DepartmentID comme champ de données valeur. Cliquez sur OK.
La méthode que vous utilisez pour associer le contrôle à l’aide d’Entity Framework est identique à celle des autres contrôles de source de données ASP.NET, sauf que vous spécifiez des entités et des propriétés d’entité.
Basculez vers la vue Source et ajoutez « Sélectionner un service : » juste avant le DropDownList contrôle.
Select a department:
<asp:DropDownList ID="DropDownList1" runat="server"
DataSourceID="EntityDataSource1" DataTextField="Name"
DataValueField="DepartmentID">
</asp:DropDownList>
Pour rappel, modifiez le balisage du contrôle EntityDataSource à ce stade en remplaçant les attributs ConnectionString et DefaultContainerName par l'attribut ContextTypeName="ContosoUniversity.DAL.SchoolEntities". Il est souvent préférable d’attendre une fois que vous avez créé le contrôle lié aux données lié au contrôle de source de données avant de modifier le balisage du EntityDataSource contrôle, car après avoir apporté la modification, le concepteur ne vous fournira pas d’option Actualiser le schéma dans le contrôle lié aux données.
Exécutez la page et vous pouvez sélectionner un service dans la liste déroulante.
Cette opération complète l’introduction à l’utilisation du EntityDataSource contrôle. L’utilisation de ce contrôle n’est généralement pas différente de l’utilisation d’autres contrôles de source de données ASP.NET, sauf que vous référencez des entités et des propriétés au lieu de tables et de colonnes. La seule exception est lorsque vous souhaitez accéder aux propriétés de navigation. Dans le tutoriel suivant, vous verrez que la syntaxe que vous utilisez avec EntityDataSource le contrôle peut également différer d’autres contrôles de source de données lorsque vous filtrez, regroupez et commandez des données.