Entity Framework 4.0 的新功能
作者 :Tom Dykstra
本教學課程系列是以 Contoso University Web 應用程式為基礎,此應用程式是由使用 Entity Framework教學課程系列消費者入門所建立。 如果您未完成先前的教學課程,作為本教學課程的起點,您可以下載您已建立 的應用程式 。 您也可以下載完整教學課程系列所建立 的應用程式 。 如果您有關于教學課程的問題,您可以將這些教學課程張貼到 ASP.NET Entity Framework 論壇。
在上一個教學課程中,您已看到一些方法,可將使用 Entity Framework 的 Web 應用程式效能最大化。 本教學課程會檢閱 Entity Framework 第 4 版中一些最重要的新功能,並連結到提供所有新功能更完整簡介的資源。 本教學課程中醒目提示的功能包括:
- 外鍵關聯。
- 執行使用者定義的 SQL 命令。
- 模型優先開發。
- POCO 支援。
此外,本教學課程會簡短介紹 程式碼優先開發,這是下一版 Entity Framework 中即將推出的功能。
若要開始本教學課程,請啟動 Visual Studio,然後開啟您在上一個教學課程中使用的 Contoso University Web 應用程式。
Foreign-Key關聯
Entity Framework 3.5 版包含導覽屬性,但未在資料模型中包含外鍵屬性。 例如, CourseID
資料表的 StudentGrade
和 StudentID
資料行會從 StudentGrade
實體中省略。
這種方法的原因是嚴格來說,外鍵是實體實作詳細資料,而且不屬於概念資料模型。 不過,在實際的情況下,當您直接存取外鍵時,使用程式碼中的實體通常比較容易。
如需資料模型中外鍵如何簡化程式碼的範例,請考慮如何在沒有外鍵的情況下撰寫 DepartmentsAdd.aspx 頁面的程式碼。 Department
在實體中 Administrator
,屬性是對應至 PersonID
實體中的 Person
外鍵。 若要建立新部門與其系統管理員之間的關聯,您只需要在資料系結控制項的事件處理常式中 ItemInserting
設定 屬性的值 Administrator
:
protected void DepartmentsDetailsView_ItemInserting(object sender, DetailsViewInsertEventArgs e)
{
e.Values["Administrator"] = administratorsDropDownList.SelectedValue;
}
如果沒有資料模型中的外鍵,您就會處理 Inserting
資料來源控制項的事件,而不是 ItemInserting
資料系結控制項的事件,以便在實體加入實體集之前取得實體本身的參考。 當您有該參考時,您可以使用類似下列範例的程式碼建立關聯:
departmentEntityToBeInserted.PersonReference.EntityKey = new System.Data.EntityKey("SchoolEntities.Departments", "PersonID", Convert.ToInt32(administratorsDropDownList.SelectedValue));
departmentEntityToBeInserted.Person = context.People.Single(p => p.PersonID == Convert.ToInt32(administratorsDropDownList.SelectedValue));
如您在 Entity Framework 小組 的外鍵關聯部落格文章中所見,在其他情況下,程式碼複雜度的差異會更大。 為了符合想要在概念性資料模型中實作詳細資料中實作詳細資料,為了簡化程式碼的需求,Entity Framework 現在可讓您選擇在資料模型中加入外鍵。
在 Entity Framework 術語中,如果您在使用 外鍵關聯的資料模型中包含外鍵,而且如果您排除使用 獨立關聯的外鍵,則為 。
執行 User-Defined SQL 命令
在舊版的 Entity Framework 中,無法輕易地即時建立您自己的 SQL 命令並加以執行。 Entity Framework 會為您動態產生 SQL 命令,或者您必須建立預存程式,並將其匯入為函式。 第 4 版會新增 ExecuteStoreQuery
和 ExecuteStoreCommand
方法類別 ObjectContext
,讓您更輕鬆地將任何查詢直接傳遞至資料庫。
假設 Contoso University 系統管理員想要能夠在資料庫中執行大量變更,而不需要完成建立預存程式並將它匯入資料模型的程式。 其第一個要求是針對頁面,讓他們變更資料庫中所有課程的點數。 在網頁上,他們想要能夠輸入數位,以用來將每個 Course
資料列的資料 Credits
行值相乘。
建立使用 Site.Master 主 版頁面的新頁面,並將它命名為 UpdateCredits.aspx。 然後將下列標記新增至名為 Content2
的 Content
控制項:
<h2>Update Credits</h2>
Enter the number to multiply the current number of credits by:
<asp:TextBox ID="CreditsMultiplierTextBox" runat="server"></asp:TextBox>
<br /><br />
<asp:Button ID="ExecuteButton" runat="server" Text="Execute" OnClick="ExecuteButton_Click" /><br /><br />
Rows affected:
<asp:Label ID="RowsAffectedLabel" runat="server" Text="0" ViewStateMode="Disabled"></asp:Label><br /><br />
此標記會 TextBox
建立控制項,讓使用者可以輸入乘數值、 Button
按一下以執行命令的控制項,以及 Label
指出受影響的資料列數目的控制項。
開啟 UpdateCredits.aspx.cs,並新增下列 using
語句和按鈕 Click
事件的處理常式:
using ContosoUniversity.DAL;
protected void ExecuteButton_Click(object sender, EventArgs e)
{
using (SchoolEntities context = new SchoolEntities())
{
RowsAffectedLabel.Text = context.ExecuteStoreCommand("UPDATE Course SET Credits = Credits * {0}", CreditsMultiplierTextBox.Text).ToString();
}
}
此程式碼會使用文字方塊中的值來執行 SQL Update
命令,並使用標籤來顯示受影響的資料列數目。 執行頁面之前,請先執行 Courses.aspx 頁面,以取得部分資料的「之前」圖片。
執行 UpdateCredits.aspx,輸入 「10」 作為乘數,然後按一下 [ 執行]。
再次執行 Courses.aspx 頁面以查看變更的資料。
(如果您想要將點數設定回其原始值,請在 UpdateCredits.aspx.cs 中變更 Credits * {0}
Credits / {0}
為 ,然後重新執行頁面,輸入 10 作為 divisor.)
如需執行您在程式碼中定義之查詢的詳細資訊,請參閱 如何:直接對資料來源執行命令。
Model-First開發
在這些逐步解說中,您會先建立資料庫,然後根據資料庫結構產生資料模型。 在 Entity Framework 4 中,您可以改為從資料模型開始,並根據資料模型結構產生資料庫。 如果您要建立資料庫不存在的應用程式,則模型優先方法可讓您建立實體和關聯性,以概念方式建立應用程式,而不必擔心實體實作詳細資料。 (這只會在開發的初始階段維持為 true。最後,資料庫將會建立並具有生產資料,並從模型重新建立它將不再實用;此時,您會回到資料庫優先方法。)
在本教學課程的本節中,您將建立簡單的資料模型,並從中產生資料庫。
在方案總管中,以滑鼠右鍵按一下DAL資料夾,然後選取 [新增專案]。 在 [ 新增專案 ] 對話方塊的 [ 已安裝的範本 ] 底下,選取 [ 資料 ],然後選取 [實體資料模型 ] 範本 ADO.NET。 將新檔案命名為 [一般][套件][關聯][Model.edmx ],然後按一下 [ 新增]。
這會啟動實體資料模型精靈。 在 [ 選擇模型內容] 步驟中,選取 [空白模型] ,然後按一下 [ 完成]。
實體資料模型Designer會以空白的設計介面開啟。 將 [實體] 專案從 [工具箱 ] 拖曳至設計介面。
將機構名稱從 Entity1
變更為 Alumnus
,將 Id
屬性名稱變更為 AlumnusId
,然後新增名為 Name
的新純量屬性。 若要新增屬性,您可以在變更資料行名稱 Id
之後按 Enter 鍵,或以滑鼠右鍵按一下實體,然後選取 [ 新增純量屬性]。 新屬性的預設類型是 String
,這適用于這個簡單的示範,但當然您可以在 [ 屬性 ] 視窗中變更資料類型之類的專案。
以相同的方式建立另一個實體,並將其命名為 Donation
。 將 Id
屬性變更為 DonationId
,並新增名為 DateAndAmount
的純量屬性。
若要新增這兩個實體之間的關聯,請以滑鼠右鍵按一下 Alumnus
實體,選取 [ 新增],然後選取 [ 關聯]。
[ 新增關聯 ] 對話方塊中的預設值是您想要 (一對多的預設值,包括導覽屬性、包含外鍵) ,因此只要按一下 [ 確定]。
設計工具會新增關聯線和外鍵屬性。
現在您已準備好建立資料庫。 以滑鼠右鍵按一下設計介面,然後 選取 [從模型產生資料庫]。
這會啟動 [產生資料庫精靈]。 (如果您看到指出實體未對應的警告,您可以忽略這些實體。)
在 [ 選擇您的資料連線] 步驟中,按一下 [ 新增連線]。
在 [連接屬性] 對話方塊中,選取本機SQL Server Express實例,並將資料庫 AlumniAssociation
命名為 。
當系統詢問您是否要建立資料庫時,請按一下 [ 是 ]。 再次顯示 [ 選擇您的資料連線 ] 步驟時,按 [ 下一步]。
在 [ 摘要和設定] 步驟中,按一下 [ 完成]。
系統會建立具有資料定義語言 (DDL) 命令的 .sql 檔案,但尚未執行命令。
使用SQL Server Management Studio之類的工具來執行腳本並建立資料表,因為您可能已在消費者入門教學課程系列的第一個教學課程建立資料庫時 School
完成。 (除非您下載 database.)
您現在 AlumniAssociation
可以使用網頁中的資料模型,就像使用 School
模型一樣。 若要嘗試這麼做,請將一些資料新增至資料表,並建立顯示資料的網頁。
使用 伺服器總管,將下列資料列新增至 Alumnus
和 Donation
資料表。
建立名為一個使用 Site.Master 主版頁面的新網頁,名為一個使用 Site.Master 主 版頁面。 將下列標記新增至名為 Content2
的 Content
控制項:
<h2>Alumni</h2>
<asp:EntityDataSource ID="AlumniEntityDataSource" runat="server"
ContextTypeName="ContosoUniversity.DAL.AlumniAssociationModelContainer" EnableFlattening="False"
EntitySetName="Alumni">
</asp:EntityDataSource>
<asp:GridView ID="AlumniGridView" runat="server"
DataSourceID="AlumniEntityDataSource" AutoGenerateColumns="False"
OnRowDataBound="AlumniGridView_RowDataBound"
DataKeyNames="AlumnusId">
<Columns>
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:TemplateField HeaderText="Donations">
<ItemTemplate>
<asp:GridView ID="DonationsGridView" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="DateAndAmount" HeaderText="Date and Amount" />
</Columns>
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
此標記會建立巢狀 GridView
控制項、外部控制項來顯示名稱,以及用來顯示賞金日期和金額的內部控制項。
開啟 一個[版面]。aspx.cs。 using
新增資料存取層的語句,以及外部 GridView
控制項 RowDataBound
事件的處理常式:
using ContosoUniversity.DAL;
// ...
protected void AlumniGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var alumnus = e.Row.DataItem as Alumnus;
var donationsGridView = (GridView)e.Row.FindControl("DonationsGridView");
donationsGridView.DataSource = alumnus.Donations.ToList();
donationsGridView.DataBind();
}
}
此程式碼會使用 Donations
目前資料列實體的 Alumnus
導覽屬性來系結內部 GridView
控制項。
執行頁面。
(附注:此頁面包含在可下載專案中,但若要讓它正常運作,您必須在本機SQL Server Express實例中建立資料庫;資料庫不會包含在App_Data資料夾中的.mdf檔案。)
如需使用 Entity Framework 模型優先功能的詳細資訊,請參閱 Entity Framework 4 中的 Model-First。
POCO 支援
當您使用領域驅動設計方法時,您會設計資料類別,這些類別代表與商務領域相關的資料和行為。 這些類別應該與用來儲存資料 (保存) 的任何特定技術無關;換句話說,它們應該是 持續性忽略的。 持續性忽略也可以讓類別更容易進行單元測試,因為單元測試專案可以使用任何持續性技術最方便進行測試。 舊版 Entity Framework 提供持續性忽略的有限支援,因為實體類別必須繼承自 類別, EntityObject
因而包含大量的 Entity Framework 特定功能。
Entity Framework 4 引進了使用未繼承自 類別的 EntityObject
實體類別的能力,因此會忽略持續性。 在 Entity Framework 的內容中,這類類別通常稱為 純舊 CLR 物件 , (POCO 或 POCO) 。 您可以手動撰寫 POCO 類別,或使用 (Entity Framework 提供的 T4) 範本,根據現有的資料模型自動產生它們。
如需在 Entity Framework 中使用 POCO 的詳細資訊,請參閱下列資源:
- 使用 POCO 實體。 這是 MSDN 檔,其概觀為 POCO,其中包含其他具有更詳細資訊的檔連結。
- 逐步解說:Entity Framework 的 POCO 範本 這是 Entity Framework 開發小組的部落格文章,其中包含有關 POCO 的其他部落格文章連結。
Code-First開發
Entity Framework 4 中的 POCO 支援仍然需要您建立資料模型,並將實體類別連結至資料模型。 Entity Framework 的下一個版本將包含稱為 程式碼優先開發的功能。 這項功能可讓您搭配自己的 POCO 類別使用 Entity Framework,而不需要使用資料模型設計工具或資料模型 XML 檔案。 (因此,此選項也稱為 僅限程式碼; 程式碼優先 和 僅限程式碼 都參考相同的 Entity Framework 功能。)
如需使用程式碼優先開發方法的詳細資訊,請參閱下列資源:
- 使用 Entity Framework 4 進行程式碼優先開發。 這是 Scott Guthrie 引進程式碼優先開發的部落格文章。
- Entity Framework 開發小組部落格 - 已標記 CodeOnly 的文章
- Entity Framework 開發小組部落格 - 標記為 Code First 的文章
- MVC 音樂市集教學課程 - 第 4 部分:模型和資料存取
- 使用 MVC 3 消費者入門 - 第 4 部分:Entity Framework Code-First開發
此外,建置類似 Contoso University 應用程式的新 MVC Code-First教學課程預計會在 2011 年 4 月發行 https://asp.net/entity-framework/tutorials
相關資訊
這會完成 Entity Framework 的新功能概觀,以及本繼續進行 Entity Framework 教學課程系列。 如需 Entity Framework 4 中未涵蓋之新功能的詳細資訊,請參閱下列資源:
- ADO.NET 的新功能 Entity Framework 第 4 版新功能的 MSDN 主題。
- 宣佈發行 Entity Framework 4 Entity Framework 開發小組有關第 4 版新功能的部落格文章。