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.
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 .
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.
Ajout d’une zone de recherche
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 leSearchTextBox
contrôle. - Remplacez la valeur de l’attribut
SelectMethod
parGetDepartmentsByName
. (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.
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.
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.