標籤:des style blog http io os 使用 ar for
這篇教程的目的是解釋在建立ASP.NET MVC應用程式時,如何使用Microsoft Entity Framework來建立資料訪問類。這篇教程假設你事先對Microsoft Entity Framework沒有任何的瞭解。讀完本篇教程,你將會理解如何使用Entity Framework來選擇、插入、更新和刪除資料庫記錄。
Microsoft Entity Framework是一個對象關係映射(O/RM)工具,它能你讓自動從資料庫產生資料訪問層。Entity Framework能夠使你免於手工編寫冗長的資料訪問類。
為了示範如何在ASP.NET MVC中使用Microsoft Entity Framework,我們將會建立一個簡單的範例應用程式。我們將會建立一個Movie資料庫應用程式,它允許你顯示和編輯Movie資料庫記錄。
這篇教程假設你擁有Visual Studio 2008或者Visual Web Developer 2008及Service Pack1。為了使用Entity Framework,你需要使用Service Pack1。你可以從下面的地址下載Visual Studio 2008 Service Pack1或者含有Service Pack1的Visual Web Developer:
http://www.asp.net/downloads/
NOTE:在ASP.NET MVC和Microsoft Entity Framework之間沒有什麼必然的聯絡。在ASP.NET MVC中除了使用Entity Framework,你還有幾個可選的方式。舉個例子,你可以使用其他的O/RM工具,例如Microsoft LINQ to SQL,NHibernate或者SubSonic來建立你的MVC模型類。
1.建立Movie範例資料庫
Movie資料庫應用程式使用叫做Movies的資料庫表格,它包含下面的列:
| 列名 |
資料類型 |
允許Null |
是否主鍵 |
| Id |
int |
False |
True |
| Title |
nvarchar(100) |
False |
False |
| Director |
nvarchar(100) |
False |
False |
你可以使用下面步驟將這個表添加到ASP.NET MVC項目中:
- 右鍵點擊“解決方案瀏覽器”中的App_Data檔案夾,並且選擇功能表項目“添加”,“建立項”。
- 在“添加新項(Add New Item)”對話方塊,選擇“SQL Server Database”,將資料庫命名為MoviesDB.mdf,並且點擊“添加(Add)”按鈕。
- 雙擊MoviesDB.mdf檔案,開啟“伺服器總管/資料庫總管”視窗。
- 展開MoviesDB.mdf資料庫連接,右鍵點擊“表”檔案夾,並且選擇菜單選項“添加新表(Add New Table)”。
- 在資料表設計工具中,添加Id、Title和Director列。
- 點擊“儲存(Save)”按鈕(它有一個磁碟片的表徵圖)將新表儲存為Movies。
在你建立好Movies資料庫表之後,你應該為表中添加一些範例資料。右鍵點擊Movies表,並且選擇功能表項目“顯示表資料(Show Table Data)”。你可以向顯示的網格中輸入一些虛構的電影資料。
2.建立ADO.NET實體資料模型
為了使用Entity Framework,你需要建立一個實體資料模型(Entity Data Model)。你可以利用Visual Studio實體資料模型嚮導(Entity Data Model Wizard)來自動從資料庫中產生一個實體資料模型。
按照下面的步驟:
- 右鍵點擊“解決方案瀏覽器”視窗中的Models檔案夾,並且選擇功能表項目,“添加(Add)”,“建立項(New Item)”。
- 在“添加新項(Add New Item)”對話方塊中,選擇Data分類(1)。
- 選擇ADO.NET Entity Data Model模板,將實體資料模型命名為MoviesDBModel.edmx,並且點擊“添加”按鈕。點擊“添加”按鈕將會運行資料模型嚮導。
- 在“選擇模型內容(Choose Model Contents)”步驟,選擇“從資料庫產生(Generate from a database)”選項,並且點擊“下一步(Next)”按鈕(2)。
- 在“選擇資料連線(Choose Your Data Conncetion)”步驟,選擇MoviesDB.mdf資料庫連接,輸入實體的串連設定名MoviesDBEntities,並且點擊“下一步”按鈕(3)。
- 在“選擇你的資料庫物件(Choose Your Database Object)”步驟,選擇Movie資料庫表,並且點擊“完成”按鈕(4)。
在你完成了這些步驟以後,將會開啟“ADO.NET實體資料模型設計器(實體設計器)”。
圖1 - 建立一個新的實體資料模型
圖2 - 選擇模型內容步驟
圖3 - 選擇資料連線
圖4 - 選擇你的資料庫物件
3.修改ADO.NET實體資料模型
在建立好實體資料模型以後,你可以利用實體設計器(5)來修改模型。通過雙擊“解決方案瀏覽器”中Models檔案夾中的MoviesDBModel.edmx檔案,你可以在任何時候開啟實體設計器。
圖5 - ADO.NET 實體資料模型設計器
舉個例子,你可以使用“實體設計器”來更改“實體模型資料嚮導”產生的類名。嚮導建立了一個叫做Movies的新的資料訪問類。換言之,Wizard對這個類的命名與資料庫中的表名完全一致。因為我們將會使用這個類來代表特定的Movie執行個體,我們應該將這個類由Movies重新命名為Movie。
如果你想要重新命名實體類,你可以在實體設計器的類名上雙擊,並且輸入一個新的名字(6)。或者,你可以在實體設計器中選擇一個實體,然後在屬性視窗中修改實體類的名字。
圖6 - 更改一個實體名
記得在做出修改後點擊“儲存”按鈕來儲存你的“實體資料模型”。在幕後,實體設計器會產生一系列的C#類。通過從“方案總管”視窗開啟MoviesDBModel.Designer.cs檔案,你可以查看這些類。
NOTE:不要在Designer.cs檔案中修改代碼,因為在下次使用實體設計器時,你的變更將會被覆蓋。如果你想要擴充定義在Designer.cs中的實體類的功能,那麼你可以在單獨的檔案中建立部分類。
4.使用Entity Framework選擇資料庫記錄
讓我們通過建立一個顯示movie記錄列表的頁面來開始構建我們的Movie資料庫應用程式。代碼1中的Home控制器發布了一個名為Index()的動作。通過使用Entity Framework,Index()動作返回了來自Movie資料庫表的所有movie記錄。
代碼清單1 - ControllersHomeController.cs
using System.Linq;
using System.Web.Mvc;
using MovieEntityApp.Models;
namespace MovieEntityApp.Controllers {
[HandleError]
public class HomeController : Controller {
MoviesDBEntities _db;
public HomeController() {
_db = new MoviesDBEntities();
}
public ActionResult Index() {
ViewData.Model = _db.MovieSet.ToList();
return View();
}
}
}
注意到代碼1中的控制器含有一個建構函式。這個建構函式初始化了一個類級的欄位,叫做_db。_db欄位代表著由Microsoft Entity Framework產生的資料庫實體。_db欄位是一個MoviesDBEntities類的執行個體,該執行個體由“實體設計器”產生。
NOTE:為了在Home控制器中使用MoviesDBEntites類,你必須引入MovieEntityApp.Models命名空間。
在Index()動作中使用了_db欄位,用於擷取Movies資料庫表中的記錄。運算式_db.MovieSet代表了所有來自Movies資料庫表的記錄。ToList()方法用於將movies記錄集轉換為一個Movie對象的泛型集合(List<Movie>)。
movie記錄在LINQ to Entities的協助下獲得。代碼1中的Index()動作使用了LINQ方法文法(method syntax)來擷取資料庫的記錄集。如果你願意,你也可以使用LINQ查詢文法(query syntax)。下面兩行陳述式完成了同樣的事情:
ViewData.Model = _db.MovieSet.ToList();
ViewData.Model = (from m in _db.MovieSet select m).ToList();
使用你最有感覺的任意一種LINQ文法――方法文法或者查詢文法。這兩種方法在效能上沒有任何區別――唯一的區別是風格。
代碼清單2中的視圖用於顯示movie記錄。
代碼清單2 - ViewsHomeIndex.aspx
<%@ Page Language="C#"
Inherits="System.Web.Mvc.ViewPage<List<MovieEntityApp.Models.Movie>>" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Index</title>
</head>
<body>
<div>
<% foreach (var m in ViewData.Model)
{ %>
Title: <%= m.Title %>
<br />
Director: <%= m.Director %>
<br />
<%= Html.ActionLink("Edit", "Edit", new { id = m.Id })%>
<%= Html.ActionLink("Delete", "Delete", new { id = m.Id })%>
<hr />
<% } %>
<%= Html.ActionLink("Add Movie", "Add") %>
</div>
</body>
</html>
代碼清單2中的視圖包含一個foreach迴圈,它遍曆了每一個movie記錄,並且顯示了movie記錄的Title和Director屬性的值。注意到在每個記錄旁邊顯示了Edit和Delete連結。除此以外,Add Movie連結顯示在視圖的底部(7)。
圖7 - Index 視圖
Index視圖是一個類型化視圖(typed view)。Index視圖包含了一個<%@ Page %>指示符,其中含有一個Inherits屬性,它將Model屬性強制轉換為了一個Movie對象的強型別泛型列表集合(List<Movie>)。
5.使用Entity Framework插入資料庫記錄
你可以使用Entity Framework輕鬆地將新紀錄插入到資料庫表中。代碼清單3包含了兩個添加到Home控制器類中的新動作,你可以使用它們來將新紀錄插入到Movie資料庫表中。
代碼清單3 - ControllersHomeController.cs(Add方法)
public ActionResult Add() {
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Add(FormCollection form) {
var movieToAdd = new Movie();
// Deserialize (Include white list!)
TryUpdateModel(movieToAdd, new string[] { "Title", "Director" }, form.ToValueProvider());
// Validate
if (String.IsNullOrEmpty(movieToAdd.Title))
ModelState.AddModelError("Title", "Title is required!");
if (String.IsNullOrEmpty(movieToAdd.Director))
ModelState.AddModelError("Director", "Director is required!");
// If valid, save movie to database
if (ModelState.IsValid)
{
_db.AddToMovieSet(movieToAdd);
_db.SaveChanges();
return RedirectToAction("Index");
}
// Otherwise, reshow form
return View(movieToAdd);
}
第一個Add()動作簡單地返回了一個視圖。這個視圖包含了一個用於添加新movie資料庫記錄的表單(8)。當你提交表單時,將會調用第二個Add()動作。
注意到第二個Add()動作使用AcceptVerbs特性進行了修飾。這個動作只有在執行HTTP POST操作的時候才會被調用。換言之,這個動作只有在提交一個HTML表單的時候會被調用。
第二個Add()動作在ASP.NET MVC TryUpdateModel()方法的協助下建立了一個Entity Framework Movie類的新執行個體。TryUpdateModel()方法接受傳遞給Add()方法的FormCollection的欄位,並且將這些HTML表單欄位的值賦值給Movie類。
NOTE:使用Entity Frmaework時,當用TryUpdateModel或者UpdateModel方法更新一個實體類的屬性時,你必須提供一個屬性的“白名單”。
接下來,Add()動作執行了一些簡單的表單驗證。該動作驗證了Title和Director屬性都有值。如果出現一個驗證錯誤,那麼一個驗證錯誤訊息將會添加到ModelState。
如果沒有驗證錯誤,那麼在Entity Framework的協助下,一個新的movie記錄將會添加到Movies資料庫表。新的記錄使用下面兩行代碼添加到資料庫中:
_db.AddToMovieSet(movieToAdd);
_db.SaveChanges();
代碼的第一行將新的Movie實體添加到由Entity Framework所追蹤的movies集中。代碼的第二行將所有對Movies的更改儲存到底層的資料庫中。
圖8 - Add 視圖
6.使用Entity Framework更新資料庫記錄
你幾乎可以按照與我們剛才插入一個新資料庫記錄相同的辦法來使用Entity Framework編輯一條資料庫記錄。代碼清單4包含了兩個新的控制器動作,叫做Edit()。第一個Edit()動作返回了一個HTML表單,用於編輯一條movie記錄。第二個Edit()動作試圖更新資料庫。
代碼清單4 - ControllersHomeController.cs(Edit方法)
public ActionResult Edit(int id)
{
// Get movie to update
var movieToUpdate = _db.MovieSet.First(m => m.Id == id);
ViewData.Model = movieToUpdate;
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(FormCollection form)
{
// Get movie to update
var id = Int32.Parse(form["id"]);
var movieToUpdate = _db.MovieSet.First(m => m.Id == id);
// Deserialize (Include white list!)
TryUpdateModel(movieToUpdate, new string[] { "Title", "Director" }, form.ToValueProvider());
// Validate
if (String.IsNullOrEmpty(movieToUpdate.Title))
ModelState.AddModelError("Title", "Title is required!");
if (String.IsNullOrEmpty(movieToUpdate.Director))
ModelState.AddModelError("Director", "Director is required!");
// If valid, save movie to database
if (ModelState.IsValid)
{
_db.SaveChanges();
return RedirectToAction("Index");
}
// Otherwise, reshow form
return View(movieToUpdate);
}
第二個Edit()動作開始時從資料庫中擷取一條與要編輯的movie的Id相匹配的Movie記錄。下面的LINQ to Entities語句擷取了匹配這一特定Id的第一條資料庫記錄。
var movieToUpdate = _db.MovieSet.First(m => m.Id == id);
接下來,TryUpdateModel()方法用於將HTML表單域的值賦給movie實體的屬性。注意到提供了一個白名單,用於指定更新哪些欄位。
下一步,執行了一些簡單的校正來驗證Movie的Title和Director屬性都有值。如果任何一個屬性缺少值,那麼一個校正錯誤訊息將會添加到ModelState,並且ModelState.IsValid將會返回false值。
最後,如果沒有校正錯誤,那麼通過調用SaveChanges()方法,底層的Movies資料庫表將會更新。
當編輯資料庫記錄時,你需要向執行資料庫更新的控制器動作傳遞要進行更新的記錄的Id。否則,控制器動作將無法知道更新底層資料庫的哪一個記錄。代碼清單5中的Edit視圖,含有一個隱藏的表單域,它代表了將要編輯的資料庫記錄的Id。
代碼清單5 - ViewsHomeEdit.aspx
<%@ Page Language="C#"
Inherits="System.Web.Mvc.ViewPage<MovieEntityApp.Models.Movie>" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Edit</title>
<style type="text/css">
.input-validation-error
{
}
</style>
</head>
<body>
<div>
<h1>Edit Movie</h1>
<form method="post" action="/Home/Edit">
<!-- Include Hidden Id -->
<%= Html.Hidden("id") %>
Title:
<br />
<%= Html.TextBox("title") %>
<br /><br />
Director:
<br />
<%= Html.TextBox("director") %>
<br /><br />
<input type="submit" value="Edit Movie" />
</form>
</div>
</body>
</html>
7.使用Entity Framework刪除資料庫記錄
在這篇教程中我們所需解決的最後一個資料庫操作,就是刪除資料庫記錄了。你可以使用代碼清單6中的控制器動作來刪除一個特定的資料庫記錄。
代碼清單6 - ControllersHomeController.cs(刪除操作)
public ActionResult Delete(int id) {
// Get movie to delete
var movieToDelete = _db.MovieSet.First(m => m.Id == id);
// Delete
_db.DeleteObject(movieToDelete);
_db.SaveChanges();
// Show Index view
return RedirectToAction("Index");
}
Delete()動作首先獲得一個Movie實體,該實體與傳遞給動作的Id相匹配。接下來,通過調用DeleteObject()方法和隨後的SaveChanges()方法,Movie從資料庫中刪除掉了。最終,使用者被重新導向到了Index視圖。
8.總結
本篇教程的目的是示範如何利用ASP.NET MVC和Microsoft Entity Framework來建立資料庫驅動的Web應用程式。你學習到了如何建立應用程式,允許你進行選擇、插入、更新和刪除資料庫記錄。
首先,我們討論了如何使用實體資料模型嚮導(Entity Data Model Wizard)從Visual Studio中產生一個實體資料模型。接下來,你學習了如何使用LINQ to Entities來從一個資料庫表中擷取一系列資料庫記錄。最後,我們使用了Entity Framework來插入、更新和刪除資料庫記錄。
本文轉載自:
http://www.cnblogs.com/JimmyZhang/archive/2009/05/18/1459326.html
Asp.Net MVC 模型(使用Entity Framework建立模型類)