使用 Entity Framework 4.0 和 ObjectDataSource 控制項,第 3 部分:排序和篩選
By Tom Dykstra
本教學課程系列是以 Contoso University Web 應用程式為基礎,此應用程式是由使用 Entity Framework 4.0教學課程系列消費者入門所建立。 如果您未完成先前的教學課程,作為本教學課程的起點,您可以下載您已建立 的應用程式 。 您也可以下載完整教學課程系列所建立 的應用程式 。 如果您有有關教學課程的問題,您可以將這些教學課程張貼至 ASP.NET Entity Framework 論壇。
在上一個教學課程中,您在使用 Entity Framework 和 ObjectDataSource
控制項的多層式 Web 應用程式中實作存放庫模式。 本教學課程說明如何進行排序和篩選,以及處理主要詳細資料案例。 您會將下列增強功能新增至 Departments.aspx 頁面:
- 文字方塊,允許使用者依名稱選取部門。
- 方格中顯示的每個部門課程清單。
- 按一下資料行標題來排序的能力。
新增排序 GridView 資料行的功能
開啟 Departments.aspx 頁面,並將屬性新增 SortParameterName="sortExpression"
至名為 的 ObjectDataSource
DepartmentsObjectDataSource
控制項。 (稍後,您將建立一個 GetDepartments
方法,其採用名為 sortExpression
.) 控制項開頭標記的標記現在類似下列範例。
<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" >
將 AllowSorting="true"
屬性新增至控制項的 GridView
開頭標記。 控制項開頭標記的標記現在類似下列範例。
<asp:GridView ID="DepartmentsGridView" runat="server" AutoGenerateColumns="False"
DataSourceID="DepartmentsObjectDataSource" DataKeyNames="DepartmentID"
OnRowUpdating="DepartmentsGridView_RowUpdating"
AllowSorting="true" >
在Departments.aspx.cs中,從 Page_Load
方法呼叫 GridView
控制項 Sort
的 方法,以設定預設排序次序:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DepartmentsGridView.Sort("Name", SortDirection.Ascending);
}
}
您可以在商務邏輯類別或存放庫類別中新增排序或篩選的程式碼。 如果您在商務邏輯類別中執行此動作,排序或篩選工作會在從資料庫擷取資料之後完成,因為商務邏輯類別正在使用 IEnumerable
存放庫傳回的物件。 如果您在存放庫類別中新增排序和篩選程式代碼,並在 LINQ 運算式或物件查詢轉換成 IEnumerable
物件之前執行此動作,您的命令將會傳遞至資料庫進行處理,這通常是更有效率的。 在本教學課程中,您將以導致資料庫完成處理的方式實作排序和篩選,也就是存放庫中的 。
若要新增排序功能,您必須將新方法新增至存放庫介面和存放庫類別,以及新增至商務邏輯類別。 在 ISchoolRepository.cs 檔案中,新增 GetDepartments
方法,其會採用 sortExpression
將用來排序所傳回部門清單的參數:
IEnumerable<Department> GetDepartments(string sortExpression);
參數 sortExpression
會指定要排序的資料行和排序方向。
將新方法的程式碼新增至 SchoolRepository.cs 檔案:
public IEnumerable<Department> GetDepartments(string sortExpression)
{
if (String.IsNullOrWhiteSpace(sortExpression))
{
sortExpression = "Name";
}
return context.Departments.Include("Person").OrderBy("it." + sortExpression).ToList();
}
變更現有的無 GetDepartments
參數方法以呼叫新的方法:
public IEnumerable<Department> GetDepartments()
{
return GetDepartments("");
}
在測試專案中,將下列新方法新增至 MockSchoolRepository.cs:
public IEnumerable<Department> GetDepartments(string sortExpression)
{
return departments;
}
如果您要建立任何相依于此方法傳回已排序清單的單元測試,您必須先排序清單,再傳回清單。 您不會在此教學課程中建立類似的測試,因此方法只能傳回未排序的部門清單。
在 SchoolBL.cs 檔案中,將下列新方法新增至商務邏輯類別:
public IEnumerable<Department> GetDepartments(string sortExpression)
{
return schoolRepository.GetDepartments(sortExpression);
}
此程式碼會將排序參數傳遞至存放庫方法。
執行 Departments.aspx 頁面。
您現在可以按一下任何資料行標題,依該資料行排序。 如果資料行已經排序,請按一下標題會反轉排序方向。
新增搜尋方塊
在本節中,您將新增搜尋文字方塊、使用控制項參數將它連結至 ObjectDataSource
控制項,並將方法新增至商務邏輯類別以支援篩選。
開啟 Departments.aspx 頁面,並在標題與第一個 ObjectDataSource
控制項之間新增下列標記:
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" />
在名為 DepartmentsObjectDataSource
的 控制項中 ObjectDataSource
,執行下列動作:
SelectParameters
為名為nameSearchString
的參數新增專案,以取得控制項中SearchTextBox
輸入的值。- 將
SelectMethod
屬性值變更為GetDepartmentsByName
。 (您稍後會建立此方法。)
控制項的 ObjectDataSource
標記現在類似下列範例:
<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>
在 ISchoolRepository.cs中,新增 GetDepartmentsByName
接受 sortExpression
和 nameSearchString
參數的方法:
IEnumerable<Department> GetDepartmentsByName(string sortExpression, string nameSearchString);
在 SchoolRepository.cs中,新增下列新方法:
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();
}
此程式碼會使用 Where
方法來選取包含搜尋字串的專案。 如果搜尋字串是空的,則會選取所有記錄。 請注意,當您在一個語句中指定方法呼叫時,例如, (Include
,然後 OrderBy
Where
) , Where
方法一律必須是最後一個。
變更採用 sortExpression
參數來呼叫新方法的現有 GetDepartments
方法:
public IEnumerable<Department> GetDepartments(string sortExpression)
{
return GetDepartmentsByName(sortExpression, "");
}
在測試專案中的 MockSchoolRepository.cs 中,新增下列新方法:
public IEnumerable<Department> GetDepartmentsByName(string sortExpression, string nameSearchString)
{
return departments;
}
在 SchoolBL.cs中,新增下列新方法:
public IEnumerable<Department> GetDepartmentsByName(string sortExpression, string nameSearchString)
{
return schoolRepository.GetDepartmentsByName(sortExpression, nameSearchString);
}
執行 Departments.aspx 頁面並輸入搜尋字串,以確定選取邏輯正常運作。 將文字方塊保留空白,並嘗試搜尋以確定傳回所有記錄。
為每個方格資料列新增詳細資料行
接下來,您想要查看方格右側儲存格中顯示的每個部門的所有課程。 若要這樣做,您將使用巢狀 GridView
控制項,並將它系結至實體導覽屬性 Department
中的資料 Courses
。
開啟 Departments.aspx ,並在 控制項的 GridView
標記中指定 事件的處理常式 RowDataBound
。 控制項開頭標記的標記現在類似下列範例。
<asp:GridView ID="DepartmentsGridView" runat="server" AutoGenerateColumns="False"
DataSourceID="DepartmentsObjectDataSource" DataKeyNames="DepartmentID"
OnRowUpdating="DepartmentsGridView_RowUpdating"
OnRowDataBound="DepartmentsGridView_RowDataBound"
AllowSorting="True" >
在範本欄位後面 Administrator
新增專案 TemplateField
:
<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>
此標記會建立巢狀 GridView
控制項,以顯示課程清單的課程編號和標題。 它不會指定資料來源,因為您將資料系結在處理常式中的程式碼中 RowDataBound
。
開啟 Departments.aspx.cs ,並新增 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();
}
}
此程式碼會從事件引數取得 Department
實體、將導覽屬性 List
轉換成 Courses
集合,並將巢狀 GridView
系結至集合的資料系結。
開啟SchoolRepository.cs檔案, Courses
並在您在 方法中 GetDepartmentsByName
建立的物件查詢中呼叫 Include
方法,以指定導覽屬性的積極式載入。 return
方法中的 GetDepartmentsByName
語句現在類似下列範例。
return context.Departments.Include("Person").Include("Courses").
OrderBy("it." + sortExpression).Where(d => d.Name.Contains(nameSearchString)).ToList();
執行頁面。 除了您稍早新增的排序和篩選功能之外,GridView 控制項現在還會顯示每個部門的巢狀課程詳細資料。
這會完成排序、篩選和主要詳細資料案例的簡介。 在下一個教學課程中,您將瞭解如何處理平行存取。
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應