解釋,不解釋:html
緊接上文,咱們在Visual Studio2012中看到系統爲咱們自動建立的視圖(View)文件Index.cshtml中,開頭有以下這句話:數據庫
@model IEnumerable<GuestBook.Models.Book>
這句話是MVC經過強類型獲取數據的方式,咱們能夠看出,在MVC視圖中使用了IEnumerable<T>接口來循環讀取數據並生成列表,該接口在System.Collections.Generic命名空間下。這就須要咱們在控制器中傳遞的數據也是IEnumerable<T>類型的。app
那麼,咱們是如何經過控制器將數據傳遞到視圖中的哪?在MVC中咱們使用數據上下文來存取數據,數據上下文是一個繼承自DbContext基類的派生類,該類定義在System.Data.Entity命名空間下,DbContext 一般將與包含模型的根實體的 DbSet<TEntity> 屬性的派生類型一塊兒使用。 DbContext簡化了實體與數據庫的溝通細節,讓咱們能夠專一於邏輯的開發,值得一提的是,在定義它的構造函數時可使用基類的構造函數指明使用數據庫的連接字符串,以下定義:函數
public MVCGuestBookContext() : base("name=DefaultConnection") { }
在使用DbContext建立派生類的實例時,會自動初始化這些根實體的 DbSet<TEntity> 集合。在DbContext這個派生類中,咱們能夠定義相似上節中的ui
public DbSet<Book> Books { get; set; }
這是一個DbSet<Tentity>泛型集合類,它爲數據上下文類提供了一個能夠訪問的屬性,該屬性指定的類型爲咱們定義的Model,如:咱們定義的Book。由於該屬性經過DbContext初始化,因此咱們利用該屬性的定義,就可使用集合的操做方式對數據進行查看等等操做。好比咱們上節中在控制器中定義了數據上下文對象:spa
private MVCGuestBookContext db = new MVCGuestBookContext();
咱們就能夠在Index動做中使用3d
var data = db.Books.ToList();
來獲取這個集合中的全部行,並經過動做中的ViewResult將data傳遞到視圖中,以下:code
return View(data);
視圖頁面經過@model 定義接收到這個data數據後,就可使用@foreach (var item in Model) 遍歷集合,獲得想要的數據列表。htm
DbContext類對象
咱們常使用自定義的數據上下文類繼承自DbContext類,由於DbContext幫咱們隱藏了與數據庫溝通的細節,僅僅經過構造函數時指明數據庫連接字符串,就能夠實現自動初始化類型爲DbSet<Tentity>泛型集合類的屬性。方便了咱們對數據的存取。該類定義以下:
命名空間: System.Data.Entity
程序集: EntityFramework(在 EntityFramework.dll 中)
public class DbContext : IDisposable, IObjectContextAdapter
該類提供了一系列的屬性和方法來進行操做,你能夠仔細閱讀MSDN中的介紹。
特別註釋:
在構造函數中,其中有一個構造函數重載是指明連接字符串。
DbContext(String) 能夠將給定字符串用做將鏈接到的數據庫的名稱或鏈接字符串來構造一個新的上下文實例。 請參見有關這如何用於建立鏈接的類備註。
在方法中,有一個SaveChanges()方法,該方法能夠將在此上下文中所作的全部更改保存到基礎數據庫。
SaveChanges 將在此上下文中所作的全部更改保存到基礎數據庫。
DbSet<TEntity>類在數據上下文中主要做用在定義該類型的屬性,利用這個屬性能夠方便對數據進行建立、讀取、更新、刪除等操做。該類定義以下:
命名空間: System.Data.Entity
程序集: EntityFramework(在 EntityFramework.dll 中)
[SuppressMessageAttribute("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix", Justification = "Name is intentional")] public class DbSet<TEntity> : DbQuery<TEntity>, IDbSet<TEntity>, IQueryable<TEntity>, IEnumerable<TEntity>, IQueryable, IEnumerable where TEntity : class
從這個類定義中,咱們能夠看出它實現了DbQuery<TEntity>, IDbSet<TEntity>, IQueryable<TEntity>, IEnumerable<TEntity>, IQueryable, IEnumerable 接口,這意味着,他可使用這些接口提供的屬性及方法來操做數據。
特別註釋:
該類具備一些實用的方法可供咱們使用,例如對數據進行操做的Add(),Find(),Remove(),須要重點介紹的是SqlQuery還可使用原生的SQL語句執行操做,十分方便,你能夠閱讀http://www.cnblogs.com/mane/p/3387960.html文章詳細瞭解,以下:
Add 將給定實體以「已添加」狀態添加到集的基礎上下文中,這樣一來,當調用 SaveChanges 時,會將該實體插入到數據庫中。
Find 查找帶給定主鍵值的實體。 若是上下文中存在帶給定主鍵值的實體,則當即返回該實體,而不會向存儲區發送請求。 不然,會向存儲區發送查找帶給定主鍵值的實體的請求,若是找到該實體,則將其附加到上下文並返回。 若是未在上下文或存儲區中找到實體,則返回 null。
Remove 將給定實體標記爲「已刪除」,這樣一來,當調用 SaveChanges 時,將從數據庫中刪除該實體。 請注意,在調用此方法以前,該實體必須以另外一種狀態存在於該上下文中。
SqlQuery 建立一個原始 SQL 查詢,該查詢將返回此集中的實體。 默認狀況下,上下文會跟蹤返回的實體;可經過對返回的 DbSqlQuery<TEntity> 調用 AsNoTracking 來更改此設置。 請注意返回實體的類型始終是此集的類型,而不會是派生的類型。 若是查詢的一個或多個表可能包含其餘實體類型的數據,則必須編寫適當的 SQL 查詢以確保只返回適當類型的實體。
另外,該類還提供了豐富的擴展方法,你能夠訪問MSDN瞭解更多詳情http://msdn.microsoft.com/query/dev11.query?appId=Dev11IDEF1&l=ZH-CN&k=k(System.Data.Entity.DbSet`1);k(DbSet%3CUser%3E);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.0);k(DevLang-csharp)&rd=true
有了上面的知識,如今,咱們能夠修改上節中的文檔實現簡單的數據插入。
MVCGuestBookContext.cs
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data.Entity;// namespace GuestBook.Models { public class MVCGuestBookContext : DbContext { public MVCGuestBookContext() : base("name=DefaultConnection") { } public DbSet<User> Users { get; set; } public DbSet<Book> Books { get; set; } } }
HomeController.cs
using System; using System.Collections.Generic; using System.Data; using System.Data.Entity; using System.Linq; using System.Web; using System.Web.Mvc; using GuestBook.Models; namespace GuestBook.Controllers { public class HomeController : Controller { private MVCGuestBookContext db = new MVCGuestBookContext(); public ActionResult Index() { var user = db.Users.Find(3); db.Books.Add(new Book() { Id = 33, Body = "這是一個正文",PublishOn=DateTime.Now, User=user}); db.SaveChanges(); return View(db.Books.ToList()); } } }
題外話:本人才疏學淺,因此不對的地方,還請各位高人指點迷津,下一節將講述另外的幾個類,以全面瞭解使用函數方式操做數據,本文全部內容都爲本人理解而寫,不表明官方定義!