消費者入門 Entity Framework 4.0 Database First 和 ASP.NET 4 Web Form - 第 3 部分
By Tom Dykstra
Contoso University 範例 Web 應用程式示範如何使用 Entity Framework 4.0 和 Visual Studio 2010 建立 ASP.NET Web Forms應用程式。 如需教學課程系列的相關資訊,請參閱 系列中的第一個教學課程
篩選、排序和分組資料
在上一個教學課程中, EntityDataSource
您已使用 控制項來顯示和編輯資料。 在本教學課程中,您將篩選、排序和群組資料。 當您藉由設定控制項的屬性 EntityDataSource
來執行此動作時,語法與其他資料來源控制項不同。 不過,如您所見,您可以使用 QueryExtender
控制項將這些差異降至最低。
您將變更 Students.aspx 頁面來篩選學生、依名稱排序,以及搜尋名稱。 您也會變更 Courses.aspx 頁面,以顯示所選部門的課程,並依名稱搜尋課程。 最後,您會將學生統計資料新增至 About.aspx 頁面。
使用 EntityDataSource 「Where」 屬性來篩選資料
開啟您在上一個教學課程中建立的 Students.aspx 頁面。 如目前設定, GridView
頁面中的控制項會顯示實體集中的所有名稱 People
。 不過,您想要只顯示學生,您可以藉由選取 Person
具有非 Null 註冊日期的實體來找到。
切換至 [設計] 檢視,然後選取 EntityDataSource
控制項。 在 [屬性] 視窗中,將 Where
屬性設定為 it.EnrollmentDate is not null
。
您在 控制項的 EntityDataSource
屬性中使用的 Where
語法為 Entity SQL。 Entity SQL 類似于 Transact-SQL,但它已自訂來搭配實體使用,而不是資料庫物件。 在運算式 it.EnrollmentDate is not null
中,這個字 it
代表查詢所傳回之實體的參考。 因此, it.EnrollmentDate
參考 EnrollmentDate
控制項傳回之 Person
實體 EntityDataSource
的 屬性。
執行頁面。 學生清單現在只包含學生。 (沒有註冊日期時,不會顯示任何資料列。)
使用 EntityDataSource 「OrderBy」 屬性來排序資料
當您第一次顯示此清單時,您也會希望此清單依名稱順序排列。 當 Students.aspx 頁面仍然在 [設計 ] 檢視中開啟,而且 EntityDataSource
在 [ 屬性 ] 視窗中,將 OrderBy 屬性設定為 it.LastName
。
執行頁面。 學生清單現在依姓氏排列順序。
使用控制項參數來設定 「Where」 屬性
如同其他資料來源控制項,您可以將參數值傳遞至 Where
屬性。 在您在教學課程的第 2 部分中建立 的 Courses.aspx 頁面上,您可以使用這個方法來顯示與使用者從下拉式清單中選取的部門相關聯的課程。
開啟 Courses.aspx ,並切換至 [設計] 檢視。 將第二 EntityDataSource
個控制項新增至頁面,並將它命名為 CoursesEntityDataSource
。 將它連接到 SchoolEntities
模型,然後選取 Courses
作為 EntitySetName 值。
在 [ 屬性 ] 視窗中,按一下 [Where ] 屬性方塊中的省略號。 (使用 [屬性] 視窗之前,請確定 CoursesEntityDataSource
仍選取控制項。)
[ 運算式編輯器 ] 對話方塊隨即顯示。 在此對話方塊中,選取 [ 根據提供的參數自動產生 Where 運算式],然後按一下 [ 新增參數]。 將參數命名為 ,選取[控制項] 作為[DepartmentID
參數來源值],然後選取[DepartmentsDropDownList] 作為ControlID值。
按一下[顯示進階屬性],然後在 [運算式編輯器] 對話方塊的 [屬性] 視窗中,將 Type
屬性變更為 Int32
。
完成後,請按一下 [確定]。
在下拉式清單下方,將控制項新增 GridView
至頁面,並將它命名為 CoursesGridView
。 將它連接到 CoursesEntityDataSource
資料來源控制項,按一下 [ 重新整理架構]、按一下 [ 編輯資料行],然後移除資料 DepartmentID
行。 控制項 GridView
標記類似下列範例。
<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>
當使用者在下拉式清單中變更選取的部門時,您希望相關聯的課程清單自動變更。 若要這樣做,請選取下拉式清單,然後在 [ 屬性 ] 視窗中將 AutoPostBack
屬性設定為 True
。
現在您已使用設計工具完成,請切換至[來源] 檢視,並將 控制項的 CoursesEntityDataSource
和 DefaultContainer
名稱屬性取代 ConnectionString
為 ContextTypeName="ContosoUniversity.DAL.SchoolEntities"
屬性。 完成時,控制項的標記看起來會像下列範例一樣。
<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>
執行頁面並使用下拉式清單來選取不同的部門。 只有所選部門所提供的課程會顯示在 控制項中 GridView
。
使用 EntityDataSource 「GroupBy」 屬性來群組資料
假設 Contoso University 想要在其 [關於] 頁面上放置一些學生主體統計資料。 具體而言,其想要依註冊日期顯示學生數目的明細。
開啟 About.aspx,然後在 [來源 ] 檢視中,將控制項的現有內容 BodyContent
取代為標記之間的 h2
「學生本文統計資料」:
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<h2>Student Body Statistics</h2>
</asp:Content>
標題之後,新增 EntityDataSource
控制項並將其命名為 StudentStatisticsEntityDataSource
。 將它連線至 SchoolEntities
,選取實體集,並將精靈中的 [ People
選取 ] 方塊保留不變。 在 [ 屬性 ] 視窗中設定下列屬性:
- 若要僅篩選學生,請將
Where
屬性設定為it.EnrollmentDate is not null
。 - 若要依註冊日期將結果分組,請將
GroupBy
屬性設定為it.EnrollmentDate
。 - 若要選取註冊日期和學生數目,請將
Select
屬性設定為it.EnrollmentDate, Count(it.EnrollmentDate) AS NumberOfStudents
。 - 若要依註冊日期排序結果,請將
OrderBy
屬性設定為it.EnrollmentDate
。
在 [來源 ] 檢視中,以 ConnectionString
屬性取代 和 DefaultContainer
名稱屬性 ContextTypeName
。 控制項 EntityDataSource
標記現在類似于下列範例。
<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>
、 和 屬性的 Select
語法類似于 Transact-SQL,但指定目前實體的關鍵字除外 it
。 Where
GroupBy
新增下列標記以建立 GridView
控制項以顯示資料。
<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>
執行頁面以查看依註冊日期顯示學生數目的清單。
使用 QueryExtender 控制項進行篩選和排序
QueryExtender
控制項提供在標記中指定篩選和排序的方法。 語法與您正在使用的資料庫管理系統無關, (DBMS) 。 它通常與 Entity Framework 無關,但除了您用於導覽屬性的語法對 Entity Framework 而言是唯一的。
在本教學課程的這個部分中,您將使用 QueryExtender
控制項來篩選和排序資料,而其中一個排序依據欄位將會是導覽屬性。
(如果您想要使用程式碼而非標記來擴充控制項自動產生的 EntityDataSource
查詢,您可以藉由處理 QueryCreated
事件來執行此動作。這是控制項延伸 EntityDataSource
控制項查詢的方式 QueryExtender
。)
開啟 Courses.aspx 頁面,並在您先前新增的標記下方,插入下列標記以建立標題、輸入搜尋字串的文字方塊、搜尋按鈕,以及 EntityDataSource
系結至實體集的 Courses
控制項。
<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>
請注意,控制項 EntityDataSource
的 Include
屬性設定為 Department
。 在資料庫中, Course
資料表不包含部門名稱;它包含 DepartmentID
外鍵資料行。 如果您直接查詢資料庫,若要取得部門名稱以及課程資料,則必須聯 Course
結 和 Department
資料表。 將 屬性設定 Include
為 Department
,即可指定 Entity Framework 應該在取得 Course
實體時執行取得相關 Department
實體的工作。 Department
實體接著會儲存在 Department
實體的 Course
導覽屬性中。 (根據預設, SchoolEntities
資料模型設計工具所產生的類別會在需要時擷取相關資料,而且您已將資料來源控制項系結至該類別,因此不需要設定 Include
屬性。不過,設定它可改善頁面的效能,因為 Entity Framework 會對資料庫進行個別呼叫,以擷取實體和相關 Department
實體的資料 Course
。)
在您剛建立的 EntityDataSource
控制項之後,插入下列標記來建立 QueryExtender
系結至該 EntityDataSource
控制項的控制項。
<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>
元素 SearchExpression
會指定您想要選取標題符合文字方塊中輸入之值的課程。 只會比較文字方塊中輸入的字元數,因為 SearchType
屬性會 StartsWith
指定 。
元素 OrderByExpression
會指定結果集會依部門名稱內的課程標題排序。 請注意如何指定部門名稱: Department.Name
。 因為實體與 Department
實體之間的 Course
關聯是一對一, Department
所以導覽屬性會 Department
包含實體。 (如果這是一對多關聯性,屬性會包含 collection.) 若要取得部門名稱,您必須指定 Name
實體的屬性 Department
。
最後,新增 GridView
控制項以顯示課程清單:
<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>
第一個資料行是顯示部門名稱的範本欄位。 資料系結運算式會 Department.Name
指定 ,就像您在 控制項中看到 QueryExtender
一樣。
執行頁面。 初始顯示會顯示依部門排序的所有課程清單,然後依課程標題顯示。
輸入 「m」,然後按一下 [ 搜尋 ] 以查看標題開頭為 「m」 的所有課程, (搜尋不區分大小寫) 。
使用 「Like」 運算子來篩選資料
您可以使用 控制項屬性中的 Where
EntityDataSource
運算子,來達到類似 QueryExtender
控制項 StartsWith
的 、 Contains
和 EndsWith
搜尋類型 Like
的效果。 在本教學課程的這個部分中,您將瞭解如何使用 Like
運算子依名稱搜尋學生。
在[來源] 檢視中開啟Students.aspx。 在 GridView
控制項之後,新增下列標記:
<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>
此標記類似于您稍早看到的內容, Where
但屬性值除外。 運算式的第二個部分 Where
會定義子字串搜尋 (LIKE %FirstMidName% or LIKE %LastName%
) ,以搜尋文字方塊中輸入之任何專案的名字和姓氏。
執行頁面。 一開始您會看到所有學生,因為參數的 StudentName
預設值為 「%」。
在文字方塊中輸入字母 「g」,然後按一下 [ 搜尋]。 您會看到名字或姓氏中有 「g」 的學生清單。
您現在已從個別資料表顯示、更新、篩選、排序和分組資料。 在下一個教學課程中,您將開始處理 (主要詳細資料) 的相關資料。