Prise en main d’Entity Framework 4.0 Database First et ASP.NET 4 Web Forms - Partie 3

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

Filtrage, classement et regroupement de données

Dans le tutoriel précédent, vous avez utilisé le EntityDataSource contrôle pour afficher et modifier des données. Dans ce tutoriel, vous allez filtrer, commander et regrouper des données. Lorsque vous effectuez cette opération en définissant des propriétés du EntityDataSource contrôle, la syntaxe est différente des autres contrôles de source de données. Toutefois, comme vous le verrez, vous pouvez utiliser le QueryExtender contrôle pour réduire ces différences.

Vous allez modifier la page Students.aspx pour filtrer les étudiants, trier par nom et rechercher sur le nom. Vous allez également modifier la page Courses.aspx pour afficher les cours du service sélectionné et rechercher des cours par nom. Enfin, vous allez ajouter des statistiques d’étudiant à la page About.aspx .

Capture d’écran de la fenêtre Internet Explorer montrant l’affichage Liste des étudiants avec une table des étudiants.

Capture d’écran de la fenêtre Internet Explorer montrant les affichages Courses by Department and Courses by Name.

Capture d’écran de la fenêtre Internet Explorer montrant l’affichage Statistiques du corps étudiant avec une table des dates d’inscription.

Capture d’écran de la fenêtre Internet Explorer montrant l’affichage Rechercher les étudiants par nom avec la lettre g entrée dans la requête de recherche.

Utilisation de la propriété EntityDataSource « Where » pour filtrer les données

Ouvrez la page Students.aspx que vous avez créée dans le didacticiel précédent. Comme configuré actuellement, le GridView contrôle de la page affiche les noms de tous les éléments du jeu d’entités People. Toutefois, vous souhaitez afficher uniquement les étudiants, ce que vous pouvez faire en sélectionnant les entités Person dont les dates d'inscription ne sont pas nulles.

Basculez vers l’affichage Création et sélectionnez le EntityDataSource contrôle. Dans la fenêtre Propriétés, définissez la propriété Where sur it.EnrollmentDate is not null.

Image01

La syntaxe que vous utilisez dans la Where propriété du EntityDataSource contrôle est Entity SQL. Entity SQL est similaire à Transact-SQL, mais il est personnalisé pour une utilisation avec des entités plutôt que des objets de base de données. Dans l’expression it.EnrollmentDate is not null, le mot it représente une référence à l’entité retournée par la requête. Par conséquent, it.EnrollmentDate fait référence à la EnrollmentDate propriété de l’entité Person retournée par le EntityDataSource contrôle.

Exécutez la page Web. La liste des étudiants contient désormais uniquement les étudiants. (Il n’y a aucune ligne affichée où il n’y a pas de date d’inscription.)

Capture d’écran de la fenêtre Internet Explorer, qui montre l’affichage Liste des étudiants avec une table des étudiants.

Utilisation de la propriété EntityDataSource « OrderBy » pour commander des données

Vous souhaitez également que cette liste soit dans l’ordre de noms lorsqu’elle est affichée pour la première fois. Avec la page Students.aspx toujours ouverte en mode Création et avec le EntityDataSource contrôle toujours sélectionné, dans la fenêtre Propriétés, définissez la propriété it.LastName sur .

Image05

Exécutez la page Web. La liste des étudiants est maintenant dans l’ordre par nom.

Image04

Utilisation d’un paramètre de contrôle pour définir la propriété « Where »

Comme avec d’autres contrôles de source de données, vous pouvez transmettre des valeurs de paramètre à la Where propriété. Dans la page Courses.aspx que vous avez créée dans la partie 2 du didacticiel, vous pouvez utiliser cette méthode pour afficher les cours associés au service sélectionné par un utilisateur dans la liste déroulante.

Ouvrez Courses.aspx et basculez en mode Création . Ajoutez un deuxième EntityDataSource contrôle à la page et nommez-le CoursesEntityDataSource. Connectez-le SchoolEntities au modèle, et sélectionnez Courses comme valeur EntitySetName.

Dans la fenêtre Propriétés, cliquez sur les points de suspension dans la zone de la propriété Where. (Vérifiez que le CoursesEntityDataSource contrôle est toujours sélectionné avant d’utiliser la fenêtre Propriétés .)

Image06

La boîte de dialogue Éditeur d’expressions s’affiche. Dans cette boîte de dialogue, sélectionnez Générer automatiquement l’expression Where en fonction des paramètres fournis, puis cliquez sur Ajouter un paramètre. Nommez le paramètre, sélectionnez DepartmentID comme valeur source du paramètre, puis sélectionnez DepartmentsDropDownList comme valeur ControlID.

Image07

Cliquez sur Afficher les propriétés avancées et, dans la fenêtre Propriétés de la boîte de dialogue Éditeur d’expressions, remplacez la propriété Typepar Int32 .

Image15

Lorsque vous avez terminé, cliquez sur OK.

Sous la liste déroulante, ajoutez un GridView contrôle à la page et nommez-le CoursesGridView. Connectez-le au contrôle de source de données, cliquez sur Actualiser le CoursesEntityDataSourceschéma, cliquez sur Modifier les colonnes, puis supprimez la DepartmentID colonne. Le balisage de contrôle GridView ressemble à l’exemple suivant.

<asp:GridView ID="CoursesGridView" runat="server" AutoGenerateColumns="False" 
        DataKeyNames="CourseID" DataSourceID="CoursesEntityDataSource">
        <Columns>
            <asp:BoundField DataField="CourseID" HeaderText="ID" ReadOnly="True" 
                SortExpression="CourseID" />
            <asp:BoundField DataField="Title" HeaderText="Title" SortExpression="Title" />
            <asp:BoundField DataField="Credits" HeaderText="Credits" 
                SortExpression="Credits" />
        </Columns>
    </asp:GridView>

Lorsque l’utilisateur modifie le service sélectionné dans la liste déroulante, vous souhaitez que la liste des cours associés change automatiquement. Pour ce faire, sélectionnez la liste déroulante et, dans la fenêtre Propriétés, définissez la propriété AutoPostBack à la valeur True.

Image08

Maintenant que vous avez terminé d’utiliser le concepteur, basculez vers la vue Source et remplacez les propriétés de nom ConnectionString et DefaultContainer du contrôle CoursesEntityDataSource par l’attribut ContextTypeName="ContosoUniversity.DAL.SchoolEntities". Lorsque vous avez terminé, le balisage du contrôle ressemblera à l’exemple suivant.

<asp:EntityDataSource ID="CoursesEntityDataSource" runat="server" 
        ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="false"
        EntitySetName="Courses" 
        AutoGenerateWhereClause="true" Where="">
        <WhereParameters>
            <asp:ControlParameter ControlID="DepartmentsDropDownList" Type="Int32" 
                Name="DepartmentID" PropertyName="SelectedValue" />
        </WhereParameters>
    </asp:EntityDataSource>

Exécutez la page et utilisez la liste déroulante pour sélectionner différents services. Seuls les cours proposés par le département sélectionné sont affichés dans l'GridView interface.

Image09

Utilisation de la propriété EntityDataSource « GroupBy » pour regrouper des données

Supposons que Contoso University souhaite placer des statistiques sur le corps des étudiants sur sa page About. Plus précisément, il veut montrer une répartition des nombres d’étudiants par date d’inscription.

Ouvrez About.aspx et, en mode Source, remplacez le contenu existant du BodyContent contrôle par « Statistiques du corps étudiant » entre les balises h2 :

<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <h2>Student Body Statistics</h2>
</asp:Content>

Après le titre, ajoutez un EntityDataSource contrôle et nommez-le StudentStatisticsEntityDataSource. Connectez-le à SchoolEntities, sélectionnez l'ensemble d'entités People et laissez la zone Sélectionner dans l’Assistant inchangée. Définissez les propriétés suivantes dans la fenêtre Propriétés :

  • Pour filtrer uniquement les étudiants, définissez la Where propriété sur it.EnrollmentDate is not null.
  • Pour regrouper les résultats par la date d’inscription, définissez la GroupBy propriété sur it.EnrollmentDate.
  • Pour sélectionner la date d’inscription et le nombre d’étudiants, définissez la propriété Select à it.EnrollmentDate, Count(it.EnrollmentDate) AS NumberOfStudents.
  • Pour classer les résultats par la date d’inscription, définissez la OrderBy propriété sur it.EnrollmentDate.

En mode Source, remplacez les propriétés de nom de ConnectionString et DefaultContainer par une propriété ContextTypeName. Le balisage de contrôle EntityDataSource ressemble maintenant à l’exemple suivant.

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

La syntaxe des propriétés Select, GroupBy, et Where ressemble à Transact-SQL, à l’exception du mot-clé it qui spécifie l’entité actuelle.

Ajoutez le balisage suivant pour créer un GridView contrôle pour afficher les données.

<asp:GridView ID="StudentStatisticsGridView" runat="server" AutoGenerateColumns="False" 
        DataSourceID="StudentStatisticsEntityDataSource">
        <Columns>
            <asp:BoundField DataField="EnrollmentDate" DataFormatString="{0:d}" 
                HeaderText="Date of Enrollment" 
                ReadOnly="True" SortExpression="EnrollmentDate" />
            <asp:BoundField DataField="NumberOfStudents" HeaderText="Students" 
                ReadOnly="True" SortExpression="NumberOfStudents" />
        </Columns>
    </asp:GridView>

Exécutez la page pour afficher une liste montrant le nombre d’étudiants par date d’inscription.

Capture d’écran de la fenêtre Internet Explorer, qui montre la vue Statistiques du corps de l’étudiant avec une table des dates d’inscription.

Utilisation du contrôle QueryExtender pour le filtrage et l’ordre

Le QueryExtender contrôle permet de spécifier le filtrage et le tri dans le balisage. La syntaxe est indépendante du système de gestion de base de données (SGBD) que vous utilisez. Elle est également généralement indépendante de Entity Framework, à l’exception que la syntaxe que vous utilisez pour les propriétés de navigation est unique à Entity Framework.

Dans cette partie du didacticiel, vous allez utiliser un QueryExtender contrôle pour filtrer et commander des données, et l’un des champs order-by est une propriété de navigation.

(Si vous préférez utiliser du code plutôt que du balisage pour étendre les requêtes générées automatiquement par le EntityDataSource contrôle, vous pouvez le faire en gérant l’événement QueryCreated . Il s’agit de la façon dont le QueryExtender contrôle étend également les EntityDataSource requêtes de contrôle.)

Ouvrez la page Courses.aspx , puis sous le balisage que vous avez ajouté précédemment, insérez le balisage suivant pour créer un titre, une zone de texte pour entrer des chaînes de recherche, un bouton de recherche et un EntityDataSource contrôle lié au Courses jeu d’entités.

<h2>Courses by Name</h2>
    Enter a course name 
    <asp:TextBox ID="SearchTextBox" runat="server"></asp:TextBox>
     <asp:Button ID="SearchButton" runat="server" Text="Search" />
    <br /><br />
    <asp:EntityDataSource ID="SearchEntityDataSource" runat="server" 
        ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" 
        EntitySetName="Courses"  
        Include="Department" >
    </asp:EntityDataSource>

Notez que la EntityDataSource propriété du Include contrôle est définie sur Department. Dans la base de données, la Course table ne contient pas le nom du service ; elle contient une DepartmentID colonne de clé étrangère. Si vous interrogiez directement la base de données pour obtenir le nom du département ainsi que les données de cours, vous devriez joindre les tables Course et Department. En définissant la propriété Include sur Department, vous spécifiez que l'Entity Framework doit obtenir l'entité associée Department lorsque vous obtenez une entité Course. L’entité Department est ensuite stockée dans la Department propriété de navigation de l’entité Course . (Par défaut, la SchoolEntities classe générée par le concepteur de modèles de données récupère les données associées quand elle est nécessaire et que vous avez lié le contrôle de source de données à cette classe, de sorte que la définition de la Include propriété n’est pas nécessaire. Toutefois, la définition améliore les performances de la page, car sinon, Entity Framework effectue des appels distincts à la base de données pour récupérer des données pour les Course entités et pour les entités associées Department .)

Après avoir créé le EntityDataSource contrôle, insérez le balisage suivant pour créer un QueryExtender contrôle lié au EntityDataSource contrôle.

<asp:QueryExtender ID="SearchQueryExtender" runat="server" 
        TargetControlID="SearchEntityDataSource" >
        <asp:SearchExpression SearchType="StartsWith" DataFields="Title">
            <asp:ControlParameter ControlID="SearchTextBox" />
        </asp:SearchExpression>
        <asp:OrderByExpression DataField="Department.Name" Direction="Ascending">
            <asp:ThenBy DataField="Title" Direction="Ascending" />            
        </asp:OrderByExpression>
    </asp:QueryExtender>

L’élément SearchExpression spécifie que vous souhaitez sélectionner des cours dont les titres correspondent à la valeur entrée dans la zone de texte. Seuls les caractères entrés dans la zone de texte sont comparés, car la SearchType propriété spécifie StartsWith.

L’élément OrderByExpression spécifie que le jeu de résultats sera classé par titre de cours dans le nom du service. Notez que le nom du service est spécifié : Department.Name. Étant donné que l’association entre l’entité Course et l’entité Department est un-à-un, la Department propriété de navigation contient une Department entité. (S’il s’agissait d’une relation un-à-plusieurs, la propriété contiendrait une collection.) Pour obtenir le nom du service, vous devez spécifier la Name propriété de l’entité Department.

Enfin, ajoutez un GridView contrôle pour afficher la liste des cours :

<asp:GridView ID="SearchGridView" runat="server" AutoGenerateColumns="False" 
        DataKeyNames="CourseID" DataSourceID="SearchEntityDataSource"  AllowPaging="true">
        <Columns>
            <asp:TemplateField HeaderText="Department">
                <ItemTemplate>
                    <asp:Label ID="Label2" runat="server" Text='<%# Eval("Department.Name") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:BoundField DataField="CourseID" HeaderText="ID"/>
            <asp:BoundField DataField="Title" HeaderText="Title" />
            <asp:BoundField DataField="Credits" HeaderText="Credits" />
        </Columns>
    </asp:GridView>

La première colonne est un champ de modèle qui affiche le nom du service. L’expression de liaison de données spécifie Department.Name, comme vous l’avez vu dans le QueryExtender contrôle.

Exécutez la page Web. L’affichage initial affiche une liste de tous les cours dans l’ordre par département, puis par titre de cours.

Capture d’écran de la fenêtre Internet Explorer, qui montre les vues Courses by Department et Courses by Name.

Entrez un « m » et cliquez sur Rechercher pour afficher tous les cours dont les titres commencent par « m » (la recherche n’est pas sensible à la casse).

Image12

Utilisation de l’opérateur « Like » pour filtrer les données

Vous pouvez obtenir un effet similaire aux types de recherche StartsWith, Contains, et EndsWith du contrôle QueryExtender en utilisant un opérateur Like dans la propriété Where du contrôle EntityDataSource. Dans cette partie du tutoriel, vous allez voir comment utiliser l’opérateur Like pour rechercher un étudiant par son nom.

Ouvrez Students.aspx en mode Source . Après le GridView contrôle, ajoutez le balisage suivant :

<h2>Find Students by Name</h2>
    Enter any part of the name
    <asp:TextBox ID="SearchTextBox" runat="server" AutoPostBack="true"></asp:TextBox>
     <asp:Button ID="SearchButton" runat="server" Text="Search" />
    <br />
    <br />
    <asp:EntityDataSource ID="SearchEntityDataSource" runat="server" 
        ContextTypeName="ContosoUniversity.DAL.SchoolEntities" EnableFlattening="False" 
        EntitySetName="People"
        Where="it.EnrollmentDate is not null and (it.FirstMidName Like '%' + @StudentName + '%' or it.LastName Like '%' + @StudentName + '%')" >
        <WhereParameters>
            <asp:ControlParameter ControlID="SearchTextBox" Name="StudentName" PropertyName="Text" 
             Type="String" DefaultValue="%"/>
        </WhereParameters>
    </asp:EntityDataSource>
    <asp:GridView ID="SearchGridView" runat="server" AutoGenerateColumns="False" DataKeyNames="PersonID"
        DataSourceID="SearchEntityDataSource" AllowPaging="true">
        <Columns>
            <asp:TemplateField HeaderText="Name" SortExpression="LastName, FirstMidName">
                <ItemTemplate>
                    <asp:Label ID="LastNameFoundLabel" runat="server" Text='<%# Eval("LastName") %>'></asp:Label>, 
                    <asp:Label ID="FirstNameFoundLabel" runat="server" Text='<%# Eval("FirstMidName") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Enrollment Date" SortExpression="EnrollmentDate">
                <ItemTemplate>
                    <asp:Label ID="EnrollmentDateFoundLabel" runat="server" Text='<%# Eval("EnrollmentDate", "{0:d}") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

Ce balisage est similaire à ce que vous avez vu précédemment, à l’exception de la valeur de propriété Where . La deuxième partie de l’expression Where définit une recherche de sous-chaîne (LIKE %FirstMidName% or LIKE %LastName%) qui recherche à la fois les prénoms et les noms de tout ce qui est entré dans la zone de texte.

Exécutez la page Web. Au départ, vous voyez tous les étudiants, car la valeur par défaut du StudentName paramètre est «%».

Image13

Entrez la lettre « g » dans la zone de texte, puis cliquez sur Rechercher. Vous voyez une liste d’étudiants qui ont un « g » dans le prénom ou le nom.

Capture d’écran de la fenêtre Internet Explorer, qui montre l’affichage Rechercher les étudiants par nom avec la lettre g entrée dans la requête de recherche.

Vous avez maintenant affiché, mis à jour, filtré, ordonné et regroupé des données à partir de tables individuelles. Dans le tutoriel suivant, vous allez commencer à utiliser des données associées (scénarios master-detail).