Verwenden von Entity Framework 4.0 und dem ObjectDataSource-Steuerelement, Teil 3: Sortieren und Filtern
von Tom Dykstra
Diese Tutorialreihe baut auf der Contoso University-Webanwendung auf, die vom Erste Schritte mit der Tutorialreihe "Entity Framework 4.0" erstellt wird. Wenn Sie die vorherigen Tutorials nicht abgeschlossen haben, können Sie als Ausgangspunkt für dieses Tutorial die Anwendung herunterladen , die Sie erstellt hätten. Sie können auch die Anwendung herunterladen , die von der vollständigen Tutorialreihe erstellt wird. Wenn Sie Fragen zu den Tutorials haben, können Sie diese im ASP.NET Entity Framework-Forum posten.
Im vorherigen Tutorial haben Sie das Repositorymuster in einer n-Schicht-Webanwendung implementiert, die das Entity Framework und das ObjectDataSource
Steuerelement verwendet. In diesem Tutorial erfahren Sie, wie Sie sortieren und filtern und master-Detailszenarien behandeln. Sie fügen der Seite Departments.aspx die folgenden Verbesserungen hinzu:
- Ein Textfeld, mit dem Benutzer Abteilungen anhand des Namens auswählen können.
- Eine Liste der Kurse für jede Abteilung, die im Raster angezeigt wird.
- Die Möglichkeit zum Sortieren durch Klicken auf Spaltenüberschriften.
Hinzufügen der Möglichkeit zum Sortieren von GridView-Spalten
Öffnen Sie die Seite Departments.aspx , und fügen Sie dem Steuerelement ein SortParameterName="sortExpression"
Attribut mit dem ObjectDataSource
Namen DepartmentsObjectDataSource
hinzu. (Später erstellen Sie eine GetDepartments
Methode, die einen Parameter namens sortExpression
akzeptiert.) Das Markup für das öffnende Tag des Steuerelements ähnelt nun dem folgenden Beispiel.
<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" >
Fügen Sie das AllowSorting="true"
Attribut dem öffnenden Tag des GridView
Steuerelements hinzu. Das Markup für das öffnende Tag des Steuerelements ähnelt nun dem folgenden Beispiel.
<asp:GridView ID="DepartmentsGridView" runat="server" AutoGenerateColumns="False"
DataSourceID="DepartmentsObjectDataSource" DataKeyNames="DepartmentID"
OnRowUpdating="DepartmentsGridView_RowUpdating"
AllowSorting="true" >
Legen Sie in Departments.aspx.cs die Standardsortierreihenfolge fest, indem Sie die GridView
-Methode des Steuerelements Sort
aus der Page_Load
-Methode aufrufen:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DepartmentsGridView.Sort("Name", SortDirection.Ascending);
}
}
Sie können Code hinzufügen, der entweder in der Geschäftslogikklasse oder in der Repositoryklasse sortiert oder filtert. Wenn Sie dies in der Geschäftslogikklasse tun, erfolgt das Sortieren oder Filtern, nachdem die Daten aus der Datenbank abgerufen wurden, da die Geschäftslogikklasse mit einem IEnumerable
objekt arbeitet, das vom Repository zurückgegeben wird. Wenn Sie der Repositoryklasse Sortier- und Filtercode hinzufügen und dies tun, bevor ein LINQ-Ausdruck oder eine Objektabfrage in ein IEnumerable
Objekt konvertiert wurde, werden Ihre Befehle zur Verarbeitung an die Datenbank übergeben, was in der Regel effizienter ist. In diesem Tutorial implementieren Sie das Sortieren und Filtern so, dass die Verarbeitung durch die Datenbank erfolgt, d. h. im Repository.
Um die Sortierfunktion hinzuzufügen, müssen Sie der Repositoryschnittstelle und den Repositoryklassen sowie der Geschäftslogikklasse eine neue Methode hinzufügen. Fügen Sie in der Datei ISchoolRepository.cs eine neue GetDepartments
Methode hinzu, die einen sortExpression
Parameter akzeptiert, der zum Sortieren der Liste der zurückgegebenen Abteilungen verwendet wird:
IEnumerable<Department> GetDepartments(string sortExpression);
Der sortExpression
Parameter gibt die zu sortierende Spalte und die Sortierrichtung an.
Fügen Sie der Datei SchoolRepository.cs Code für die neue Methode hinzu:
public IEnumerable<Department> GetDepartments(string sortExpression)
{
if (String.IsNullOrWhiteSpace(sortExpression))
{
sortExpression = "Name";
}
return context.Departments.Include("Person").OrderBy("it." + sortExpression).ToList();
}
Ändern Sie die vorhandene parameterlose GetDepartments
Methode, um die neue Methode aufzurufen:
public IEnumerable<Department> GetDepartments()
{
return GetDepartments("");
}
Fügen Sie im Testprojekt die folgende neue Methode zu MockSchoolRepository.cs hinzu:
public IEnumerable<Department> GetDepartments(string sortExpression)
{
return departments;
}
Wenn Sie Komponententests erstellen möchten, die von dieser Methode abhängen und eine sortierte Liste zurückgeben, müssen Sie die Liste sortieren, bevor Sie sie zurückgeben. In diesem Tutorial erstellen Sie keine Tests wie diese, sodass die Methode einfach die unsortierte Liste der Abteilungen zurückgeben kann.
Fügen Sie in der Datei SchoolBL.cs der Geschäftslogikklasse die folgende neue Methode hinzu:
public IEnumerable<Department> GetDepartments(string sortExpression)
{
return schoolRepository.GetDepartments(sortExpression);
}
Dieser Code übergibt den Sortierparameter an die Repositorymethode.
Führen Sie die Seite Departments.aspx aus .
Sie können jetzt auf eine beliebige Spaltenüberschrift klicken, um nach dieser Spalte zu sortieren. Wenn die Spalte bereits sortiert ist, wird durch Klicken auf die Überschrift die Sortierrichtung umgekehrt.
Hinzufügen eines Suchfelds
In diesem Abschnitt fügen Sie ein Suchtextfeld hinzu, verknüpfen es mit dem ObjectDataSource
Steuerelement mithilfe eines Steuerelementparameters und fügen der Geschäftslogikklasse eine Methode zur Unterstützung der Filterung hinzu.
Öffnen Sie die Seite Departments.aspx , und fügen Sie das folgende Markup zwischen der Überschrift und dem ersten ObjectDataSource
Steuerelement hinzu:
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" />
Führen Sie im ObjectDataSource
-Steuerelement mit dem Namen DepartmentsObjectDataSource
die folgenden Schritte aus:
- Fügen Sie ein
SelectParameters
Element für einen Parameter namensnameSearchString
hinzu, der den in das Steuerelement eingegebenenSearchTextBox
Wert abruft. - Ändern Sie den
SelectMethod
Attributwert inGetDepartmentsByName
. (Sie erstellen diese Methode später.)
Das Markup für das ObjectDataSource
Steuerelement ähnelt nun dem folgenden Beispiel:
<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>
Fügen Sie in ISchoolRepository.cs eine GetDepartmentsByName
Methode hinzu, die sowohl parameter als auch sortExpression
nameSearchString
akzeptiert:
IEnumerable<Department> GetDepartmentsByName(string sortExpression, string nameSearchString);
Fügen Sie in SchoolRepository.cs die folgende neue Methode hinzu:
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();
}
Dieser Code verwendet eine Where
-Methode, um Elemente auszuwählen, die die Suchzeichenfolge enthalten. Wenn die Suchzeichenfolge leer ist, werden alle Datensätze ausgewählt. Beachten Sie, dass beim Angeben von Methodenaufrufen in einer Anweisung wie dieser (Include
, dann OrderBy
) Where
die Where
Methode immer die letzte sein muss.
Ändern Sie die vorhandene GetDepartments
Methode, die einen sortExpression
Parameter verwendet, um die neue Methode aufzurufen:
public IEnumerable<Department> GetDepartments(string sortExpression)
{
return GetDepartmentsByName(sortExpression, "");
}
Fügen Sie in MockSchoolRepository.cs im Testprojekt die folgende neue Methode hinzu:
public IEnumerable<Department> GetDepartmentsByName(string sortExpression, string nameSearchString)
{
return departments;
}
Fügen Sie in SchoolBL.cs die folgende neue Methode hinzu:
public IEnumerable<Department> GetDepartmentsByName(string sortExpression, string nameSearchString)
{
return schoolRepository.GetDepartmentsByName(sortExpression, nameSearchString);
}
Führen Sie die Seite Departments.aspx aus , und geben Sie eine Suchzeichenfolge ein, um sicherzustellen, dass die Auswahllogik funktioniert. Lassen Sie das Textfeld leer, und versuchen Sie eine Suche, um sicherzustellen, dass alle Datensätze zurückgegeben werden.
Hinzufügen einer Detailspalte für jede Rasterzeile
Als Nächstes möchten Sie alle Kurse für jede Abteilung anzeigen, die in der rechten Zelle des Rasters angezeigt werden. Dazu verwenden Sie ein geschachteltes GridView
Steuerelement und binden es an Daten aus der Courses
Navigationseigenschaft der Department
Entität.
Öffnen Sie Departments.aspx , und geben Sie im Markup für das GridView
Steuerelement einen Handler für das RowDataBound
Ereignis an. Das Markup für das öffnende Tag des Steuerelements ähnelt nun dem folgenden Beispiel.
<asp:GridView ID="DepartmentsGridView" runat="server" AutoGenerateColumns="False"
DataSourceID="DepartmentsObjectDataSource" DataKeyNames="DepartmentID"
OnRowUpdating="DepartmentsGridView_RowUpdating"
OnRowDataBound="DepartmentsGridView_RowDataBound"
AllowSorting="True" >
Fügen Sie nach dem Administrator
Vorlagenfeld ein neues TemplateField
Element hinzu:
<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>
Dieses Markup erstellt ein geschachteltes GridView
Steuerelement, das die Kursnummer und den Titel einer Liste von Kursen anzeigt. Es wird keine Datenquelle angegeben, da Sie sie im Code des RowDataBound
Handlers mit Daten binden.
Öffnen Sie Departments.aspx.cs , und fügen Sie den folgenden Handler für das RowDataBound
Ereignis hinzu:
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();
}
}
Dieser Code ruft die Department
Entität aus den Ereignisargumenten ab, konvertiert die Courses
Navigationseigenschaft in eine List
Sammlung und bindet die geschachtelte GridView
an die Auflistung.
Öffnen Sie die Datei SchoolRepository.cs , und geben Sie eager loading für die Courses
Navigationseigenschaft an, indem Sie die Include
-Methode in der Objektabfrage aufrufen, die Sie in der GetDepartmentsByName
-Methode erstellen. Die return
-Anweisung in der GetDepartmentsByName
-Methode ähnelt nun dem folgenden Beispiel.
return context.Departments.Include("Person").Include("Courses").
OrderBy("it." + sortExpression).Where(d => d.Name.Contains(nameSearchString)).ToList();
Führen Sie die Seite aus. Zusätzlich zu der Zuvor hinzugefügten Sortier- und Filterfunktion zeigt das GridView-Steuerelement jetzt geschachtelte Kursdetails für jede Abteilung an.
Dies schließt die Einführung in Sortier-, Filter- und master-Detailszenarien ab. Im nächsten Tutorial erfahren Sie, wie Sie die Parallelität behandeln.
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für