Asp.Net MVC 模型(使用Entity Framework创建模型类)
Asp.Net MVC 模型(使用Entity Framework創建模型類)
這篇教程的目的是解釋在創建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項目中:
在你創建好Movies數據庫表之后,你應該為表中添加一些范例數據。右鍵點擊Movies表,并且選擇菜單項“顯示表數據(Show Table Data)”。你可以向顯示的網格中輸入一些虛構的電影數據。
2.創建ADO.NET實體數據模型
為了使用Entity Framework,你需要創建一個實體數據模型(Entity Data Model)。你可以利用Visual Studio實體數據模型向導(Entity Data Model Wizard)來自動從數據庫中生成一個實體數據模型。
按照下面的步驟:
在你完成了這些步驟以后,將會打開“ADO.NET實體數據模型設計器(實體設計器)”。
圖1 - 創建一個新的實體數據模型
圖2 - 選擇模型內容步驟
圖3 - 選擇數據連接
圖4 - 選擇你的數據庫對象
3.修改ADO.NET實體數據模型
在創建好實體數據模型以后,你可以利用實體設計器(如圖5)來修改模型。通過雙擊“解決方案瀏覽器”中Models文件夾中的MoviesDBModel.edmx文件,你可以在任何時候打開實體設計器。
圖5 - ADO.NET 實體數據模型設計器
舉個例子,你可以使用“實體設計器”來更改“實體模型數據向導”生成的類名。向導創建了一個叫做Movies的新的數據訪問類。換言之,Wizard對這個類的命名與數據庫中的表名完全一致。因為我們將會使用這個類來代表特定的Movie實例,我們應該將這個類由Movies重命名為Movie。
如果你想要重命名實體類,你可以在實體設計器的類名上雙擊,并且輸入一個新的名字(如圖6)?;蛘?#xff0c;你可以在實體設計器中選擇一個實體,然后在屬性窗口中修改實體類的名字。
圖6 - 更改一個實體名
記得在做出修改后點擊“保存”按鈕來保存你的“實體數據模型”。在幕后,實體設計器會生成一系列的C#類。通過從“解決方案資源管理器”窗口打開MoviesDBModel.Designer.cs文件,你可以查看這些類。
NOTE:不要在Designer.cs文件中修改代碼,因為在下次使用實體設計器時,你的變更將會被覆蓋。如果你想要擴展定義在Designer.cs中的實體類的功能,那么你可以在單獨的文件中創建部分類。
4.使用Entity Framework選擇數據庫記錄
讓我們通過創建一個顯示movie記錄列表的頁面來開始構建我們的Movie數據庫應用程序。代碼1中的Home控制器發布了一個名為Index()的動作。通過使用Entity Framework,Index()動作返回了來自Movie數據庫表的所有movie記錄。
代碼清單1 - Controllers\HomeController.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 - Views\Home\Index.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 - Controllers\HomeController.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 - Controllers\HomeController.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 - Views\Home\Edit.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
??? {
??????? background-color:Yellow;
??? }
???
??? </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 - \Controllers\HomeController.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來插入、更新和刪除數據庫記錄。
轉載于:https://www.cnblogs.com/millen/archive/2009/12/17/1626531.html
總結
以上是生活随笔為你收集整理的Asp.Net MVC 模型(使用Entity Framework创建模型类)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iPhone如何设置黑名单?
- 下一篇: 字符编码解码整合工具