Partager via


Utilisation d’Entity Framework 4.0 et du contrôle ObjectDataSource, partie 3 : Tri et filtrage

par Tom Dykstra

Cette série de tutoriels s’appuie sur l’application web Contoso University créée par le Prise en main avec la série de tutoriels Entity Framework 4.0. Si vous n’avez pas terminé les didacticiels précédents, comme point de départ de ce tutoriel, vous pouvez télécharger l’application que vous auriez créée. Vous pouvez également télécharger l’application créée par la série complète de tutoriels. Si vous avez des questions sur les tutoriels, vous pouvez les publier sur le forum ASP.NET Entity Framework.

Dans le tutoriel précédent, vous avez implémenté le modèle de dépôt dans une application web à plusieurs niveaux qui utilise Entity Framework et le ObjectDataSource contrôle. Ce tutoriel montre comment trier et filtrer et gérer des scénarios master détail. Vous allez ajouter les améliorations suivantes à la page Departments.aspx :

  • Zone de texte permettant aux utilisateurs de sélectionner des services par nom.
  • Liste des cours pour chaque service affiché dans la grille.
  • Possibilité de trier en cliquant sur les en-têtes de colonne.

Capture d’écran montrant la page Départements prête pour des améliorations.

Ajout de la possibilité de trier des colonnes GridView

Ouvrez la page Departments.aspx et ajoutez un SortParameterName="sortExpression" attribut au ObjectDataSource contrôle nommé DepartmentsObjectDataSource. (Plus tard, vous créerez une GetDepartments méthode qui prend un paramètre nommé sortExpression.) Le balisage de la balise d’ouverture du contrôle ressemble maintenant à l’exemple suivant.

<asp:ObjectDataSource ID="DepartmentsObjectDataSource" runat="server" 
        TypeName="ContosoUniversity.BLL.SchoolBL" DataObjectTypeName="ContosoUniversity.DAL.Department" 
        SelectMethod="GetDepartments" DeleteMethod="DeleteDepartment" UpdateMethod="UpdateDepartment"
        ConflictDetection="CompareAllValues" OldValuesParameterFormatString="orig{0}" 
        OnUpdated="DepartmentsObjectDataSource_Updated" SortParameterName="sortExpression" >

Ajoutez l’attribut AllowSorting="true" à la balise d’ouverture du GridView contrôle. Le balisage de la balise d’ouverture du contrôle ressemble maintenant à l’exemple suivant.

<asp:GridView ID="DepartmentsGridView" runat="server" AutoGenerateColumns="False"
        DataSourceID="DepartmentsObjectDataSource" DataKeyNames="DepartmentID" 
        OnRowUpdating="DepartmentsGridView_RowUpdating"
        AllowSorting="true" >

Dans Departments.aspx.cs, définissez l’ordre de tri par défaut en appelant la GridView méthode du Sort contrôle à partir de la Page_Load méthode :

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        DepartmentsGridView.Sort("Name", SortDirection.Ascending);
    }
}

Vous pouvez ajouter du code qui trie ou filtre dans la classe logique métier ou dans la classe référentiel. Si vous le faites dans la classe de logique métier, le travail de tri ou de filtrage sera effectué une fois les données récupérées à partir de la base de données, car la classe logique métier fonctionne avec un IEnumerable objet retourné par le référentiel. Si vous ajoutez du code de tri et de filtrage dans la classe du référentiel et que vous le faites avant qu’une expression LINQ ou une requête d’objet IEnumerable n’ait été convertie en objet, vos commandes sont transmises à la base de données pour traitement, ce qui est généralement plus efficace. Dans ce tutoriel, vous allez implémenter le tri et le filtrage de manière à ce que le traitement soit effectué par la base de données, c’est-à-dire dans le dépôt.

Pour ajouter une fonctionnalité de tri, vous devez ajouter une nouvelle méthode à l’interface de dépôt et aux classes de référentiel, ainsi qu’à la classe logique métier. Dans le fichier ISchoolRepository.cs , ajoutez une nouvelle GetDepartments méthode qui prend un sortExpression paramètre qui sera utilisé pour trier la liste des services retournés :

IEnumerable<Department> GetDepartments(string sortExpression);

Le sortExpression paramètre spécifie la colonne sur laquelle trier et le sens du tri.

Ajoutez le code de la nouvelle méthode au fichier SchoolRepository.cs :

public IEnumerable<Department> GetDepartments(string sortExpression)
{
    if (String.IsNullOrWhiteSpace(sortExpression))
    {
        sortExpression = "Name";
    }
    return context.Departments.Include("Person").OrderBy("it." + sortExpression).ToList();
}

Modifiez la méthode sans GetDepartments paramètre existante pour appeler la nouvelle méthode :

public IEnumerable<Department> GetDepartments()
{
    return GetDepartments("");
}

Dans le projet de test, ajoutez la nouvelle méthode suivante à MockSchoolRepository.cs :

public IEnumerable<Department> GetDepartments(string sortExpression)
{
    return departments;
}

Si vous deviez créer des tests unitaires qui dépendaient de cette méthode renvoyant une liste triée, vous devez trier la liste avant de la renvoyer. Vous ne créerez pas de tests comme celui-ci dans ce tutoriel. La méthode peut donc simplement retourner la liste non triée des services.

Dans le fichier SchoolBL.cs , ajoutez la nouvelle méthode suivante à la classe de logique métier :

public IEnumerable<Department> GetDepartments(string sortExpression)
{
    return schoolRepository.GetDepartments(sortExpression);
}

Ce code transmet le paramètre de tri à la méthode de dépôt.

Exécutez la page Departments.aspx .

Image02

Vous pouvez maintenant cliquer sur n’importe quel en-tête de colonne pour trier selon cette colonne. Si la colonne est déjà triée, cliquer sur le titre inverse le sens du tri.

Dans cette section, vous allez ajouter une zone de texte de recherche, la lier au contrôle à l’aide d’un paramètre de contrôle et ajouter une méthode à la classe de logique métier pour prendre en charge le ObjectDataSource filtrage.

Ouvrez la page Departments.aspx et ajoutez le balisage suivant entre le titre et le premier ObjectDataSource contrôle :

Enter any part of the name or leave the box blank to see all names:
    <asp:TextBox ID="SearchTextBox" runat="server" AutoPostBack="true"></asp:TextBox>
     <asp:Button ID="SearchButton" runat="server" Text="Search" />

Dans le ObjectDataSource contrôle nommé DepartmentsObjectDataSource, procédez comme suit :

  • Ajoutez un SelectParameters élément pour un paramètre nommé nameSearchString qui obtient la valeur entrée dans le SearchTextBox contrôle.
  • Remplacez la valeur de l’attribut SelectMethod par GetDepartmentsByName. (Vous créerez cette méthode ultérieurement.)

Le balisage du ObjectDataSource contrôle ressemble maintenant à l’exemple suivant :

<asp:ObjectDataSource ID="DepartmentsObjectDataSource" runat="server" TypeName="ContosoUniversity.BLL.SchoolBL"
        SelectMethod="GetDepartmentsByName" DeleteMethod="DeleteDepartment" UpdateMethod="UpdateDepartment"
        DataObjectTypeName="ContosoUniversity.DAL.Department" ConflictDetection="CompareAllValues"
        SortParameterName="sortExpression" OldValuesParameterFormatString="orig{0}" 
        OnUpdated="DepartmentsObjectDataSource_Updated">
        <SelectParameters>
            <asp:ControlParameter ControlID="SearchTextBox" Name="nameSearchString" PropertyName="Text"
                Type="String" />
        </SelectParameters>
    </asp:ObjectDataSource>

Dans ISchoolRepository.cs, ajoutez une GetDepartmentsByName méthode qui prend à la fois les sortExpression paramètres et nameSearchString :

IEnumerable<Department> GetDepartmentsByName(string sortExpression, string nameSearchString);

Dans SchoolRepository.cs, ajoutez la nouvelle méthode suivante :

public IEnumerable<Department> GetDepartmentsByName(string sortExpression, string nameSearchString)
{
    if (String.IsNullOrWhiteSpace(sortExpression))
    {
        sortExpression = "Name";
    }
    if (String.IsNullOrWhiteSpace(nameSearchString))
    {
        nameSearchString = "";
    }
    return context.Departments.Include("Person").OrderBy("it." + sortExpression).Where(d => d.Name.Contains(nameSearchString)).ToList();
}

Ce code utilise une Where méthode pour sélectionner les éléments qui contiennent la chaîne de recherche. Si la chaîne de recherche est vide, tous les enregistrements sont sélectionnés. Notez que lorsque vous spécifiez des appels de méthode dans une instruction comme celle-ci (Include, puis OrderBy, puis Where), la Where méthode doit toujours être la dernière.

Modifiez la méthode existante GetDepartments qui prend un sortExpression paramètre pour appeler la nouvelle méthode :

public IEnumerable<Department> GetDepartments(string sortExpression)
{
    return GetDepartmentsByName(sortExpression, "");
}

Dans MockSchoolRepository.cs dans le projet de test, ajoutez la nouvelle méthode suivante :

public IEnumerable<Department> GetDepartmentsByName(string sortExpression, string nameSearchString)
{
    return departments;
}

Dans SchoolBL.cs, ajoutez la nouvelle méthode suivante :

public IEnumerable<Department> GetDepartmentsByName(string sortExpression, string nameSearchString)
{
    return schoolRepository.GetDepartmentsByName(sortExpression, nameSearchString);
}

Exécutez la page Departments.aspx et entrez une chaîne de recherche pour vous assurer que la logique de sélection fonctionne. Laissez la zone de texte vide et essayez une recherche pour vous assurer que tous les enregistrements sont retournés.

Image03

Ajout d’une colonne de détails pour chaque ligne de grille

Ensuite, vous souhaitez voir tous les cours de chaque service affichés dans la cellule de droite de la grille. Pour ce faire, vous allez utiliser un contrôle imbriqué GridView et le lier aux données de la Courses propriété de navigation de l’entité Department .

Ouvrez Departments.aspx et dans le balisage du GridView contrôle, spécifiez un gestionnaire pour l’événement RowDataBound . Le balisage de la balise d’ouverture du contrôle ressemble maintenant à l’exemple suivant.

<asp:GridView ID="DepartmentsGridView" runat="server" AutoGenerateColumns="False"
        DataSourceID="DepartmentsObjectDataSource" DataKeyNames="DepartmentID" 
        OnRowUpdating="DepartmentsGridView_RowUpdating"
        OnRowDataBound="DepartmentsGridView_RowDataBound"
        AllowSorting="True" >

Ajoutez un nouvel TemplateField élément après le champ de Administrator modèle :

<asp:TemplateField HeaderText="Courses">
                <ItemTemplate>
                    <asp:GridView ID="CoursesGridView" runat="server" AutoGenerateColumns="False">
                        <Columns>
                            <asp:BoundField DataField="CourseID" HeaderText="ID" />
                            <asp:BoundField DataField="Title" HeaderText="Title" />
                        </Columns>
                    </asp:GridView>
                </ItemTemplate>
            </asp:TemplateField>

Ce balisage crée un contrôle imbriqué GridView qui affiche le numéro de cours et le titre d’une liste de cours. Il ne spécifie pas de source de données, car vous allez la lier dans du code dans le RowDataBound gestionnaire.

Ouvrez Departments.aspx.cs et ajoutez le gestionnaire suivant pour l’événement RowDataBound :

protected void DepartmentsGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        var department = e.Row.DataItem as Department;
        var coursesGridView = (GridView)e.Row.FindControl("CoursesGridView");
        coursesGridView.DataSource = department.Courses.ToList();
        coursesGridView.DataBind();
    }
}

Ce code obtient l’entité Department à partir des arguments d’événement, convertit la Courses propriété de navigation en collection List et relie le imbriqué GridView à la collection.

Ouvrez le fichier SchoolRepository.cs et spécifiez un chargement pressé pour la Courses propriété de navigation en appelant la Include méthode dans la requête d’objet que vous créez dans la GetDepartmentsByName méthode. L’instruction return de la GetDepartmentsByName méthode ressemble maintenant à l’exemple suivant.

return context.Departments.Include("Person").Include("Courses").
    OrderBy("it." + sortExpression).Where(d => d.Name.Contains(nameSearchString)).ToList();

Exécutez la page. En plus de la fonctionnalité de tri et de filtrage que vous avez ajoutée précédemment, le contrôle GridView affiche désormais les détails des cours imbriqués pour chaque service.

Capture d’écran montrant le contrôle Grid View affichant les détails du cours imbriqué.

Ceci termine l’introduction aux scénarios de tri, de filtrage et de master détails. Dans le tutoriel suivant, vous allez voir comment gérer la concurrence.