在開發應用程序的過程當中,常常須要處理許多大大小小的數據,例如,SQL Server數據庫存取、鏈接AD(Active Directory)數據庫進行驗證、調用外部Web Service取得數據等。除了訪問數據外,也常常須要對數據作成格式驗證、邏輯驗證等等。html
1、Model的責任web
在ASP.NET MVC中,Model負責全部與「數據」有關的任務。因此,不論是Controller或是View,都會參考到Model裏定義的全部數據類型,或是用到Model裏定義的一些數據操做方法,例如,新增、刪除、更改、查詢等。數據庫
在Model裏的程序,因爲「只能」跟數據域商業邏輯有關,因此就不負責處理全部與數據處理無關的事,或是用來控制網站的運行流程等,而是專一於如何有效率地提供數據訪問機制、交易環境、數據格式驗證、商業邏輯驗證等工做。編程
因爲Model的獨立性很是高,若是你在一個Visual Studio方案中,有多個要開發的項目,好比有時咱們會將Model獨立成一個項目,讓Model項目共享於不一樣的項目之間。服務器
2、開發Model的基本觀念數據結構
當採用ASP.NET MVC框架時,雖然在Model層的開發技術繁多,並且ASP.NET MVC也保留了許多彈性,讓各個不一樣的數據訪問技術都能跟ASP.NET MVC集成。不過,若要充分發揮ASP.NET MVC快速開發的優點,仍是建議讀者在Model層採用ORM信息訪問技術來開發,例如,LINQ to SQL、Entity Framework、NHibernate、Telerik OpenAccess ORM等。架構
1.何謂ORMapp
ORM的全名是Object Relational Mapping,中文翻譯爲「對象關係映射」,是一種編程技術,用於實現面向對象程序語言裏,不一樣類型系統之間的數據轉換。一般在實務的應用上,大多數狀況都會應用在數據庫與面向對象程序自檢的類型轉換,例如,SQL Server中的關係型數據與.NET類型對象之間的轉換等。框架
換句話說,ORM是將結構化的關係型數據,映射成面向對象模型。若是以Entity Framework來講,就是試圖將關係數據庫的各類數據轉換成.NET原生對象,或是將.NET模型類對象數據轉換成關係型數據。函數
使用ORM開發技術跟常規使用ADO.NET開發技術最大的差別,就在於操做「數據」的方便性與彈性。以往在使用ADO.NET開發數據訪問程序時,開發人員一般必須先了解完整的數據庫操做方法,才能順利地從數據庫取得數據,或是將對象的數據保存到數據庫中。例如,要編寫操做SQL Server數據庫中的數據,就必須先學習T-SQL的使用方式;若要操做Oracle數據庫中的數據,也必須先學習Oracle的SQL查詢語法。學會以後還要學習各式ADO.NET的標準API,才能知道如何正確地與數據庫交互,明白是要進行查詢數據、更新數據、新增數據仍是刪除數據等。不一樣的數據庫,在設計邏輯與SQL語法上都會有些小差別,而致使開發數據訪問的程序代碼缺少效率。如此一來,也有違「關注點分離」的特性,如果套用「關注點分離」特性,照理說在開發.NET應用程序時,應該專一在對象的操做上,而非數據庫數據的處理,當採用ORM開發技術後,即可以幫助咱們達到這個目的。
Entity Framwork是建構在ADO.NET數據提供者模型之上,也就是說,只要.NET運行環境可以使用ADO.NET鏈接數據庫,Enity Framework便能順利支持,在.NET運行環境下默認已經支持SQL Server 2005以上版本,若是要支持其餘如Oracle、MySQL、SQLite、PostgreSQL等各式各樣的關係數據庫基本上也是沒問題的,只要操做出相對應的Entity Framework數據提供者便可。
2.數據庫開發模式
採用Entity Framework或其餘ORM開發極速,有時還可區分三種不一樣的開發模式,分別是數據庫優先開發模式(Database First Development)、模型優先開發模式(Model First Development)、程序代碼優先開發模式(Code First Development)。
(1)數據庫優先開發模式
顧名思義,數據庫優先開發模式就是針對數據庫進行設計,以數據庫裏定義的數據結構(Schema)爲主。當應用程序在卡法的時候,必須依據數據庫的結構設計來進行開發,使用的ORM框架必須可以依據數據庫結構設計生成相應的對象模型,才能提供給應用程序來使用。
(2)模型優先開發模式
模型優先開發模式是指在ORM架構中建立對象模型,讓應用程序可以依據這些對象模型進行開發。須要實際訪問數據庫時,只要經過Entity Framework數據提供者的協助,動態生成相應的SQL語法,便可建立出完整的數據庫。
通常來講,支持模型優先開發模式的ORM框架,都會有相對應的程序代碼生成技術,在模型被建立的同時自動生成相對應的程序代碼。以Entity Framework爲例,在搭配Visual Studio的幫助下,便可經過Entity Framework設計工具,幫你建立對象模型,只要保存後,就會自動生成相關程序代碼。
(3)程序代碼優先開發模式
程序代碼優先開發模式是一種很是新穎的開發模式,也就是讓開發人員直接依據需求,編寫類別與屬性(程序代碼),而這些撰寫的類別與屬性正是定義出應用程序所需的數據模型,而且經過ORM框架的管理,即可讓這些POCO類型,轉換成實體模型(Entity Model)。
直到程序開始運行後,經過ORM框架,就能夠自動依據這些類別,定義建立數據庫、表格、字段與其餘數據結構(Schema)。這樣開發人員即可以徹底不須要接觸數據庫這一端的各類管理工做(如建立表格字段、設計數據表、設計數據表關聯等),也不用學習各式數據庫的使用差別(如SQL Server、Oracle、MySQL、SQLite等),省去這些工做以後,開發人員更能專一在應用程序的需求開發,而不會由於不熟悉數據庫操做而束手束腳。
3、LocalDB介紹
微軟最新推出的SQL Server 2012 Express LocalDB,是一種SQL Server Express的運行模式,特別適合在開發環境使用,也內建在Visual Studio 2012之中。
1.LocalDB的運做方式
在安裝好SQL Server 2012 Express LocalDB以後,默認會有個實例名,爲v11.0。
2.如何鏈接LocalDB實例
(1)使用Management Studio鏈接LocalDB
在鏈接對話框中輸入正確服務器名稱,(localdb)\v11.0。只有新版的SQL Server 2012 Management Studio才能識別這組新的服務器名稱。
(2)經過.NET程序鏈接LocalDB實例
鏈接字符串以下。
Server=(LocalDB)\v11.0; Integrated Security=true; AttachDbFileName=D:\Data\MyDB1.mdf
3.管理LocalDB自動實例
4.管理LocalDB具名實例
4、使用Code First建立數據模型
ASP.NET MVC4與當前最新版的Entity Framework 5同時上市,尤爲強化了程序代碼優先開發模式的支持。
1.建立數據模型
(1)聲明主鍵
要想在Entity Framework聲明主鍵,最簡單的方式就是不要聲明,直接把屬性名稱設置爲Id或是類名+「Id」也能夠,並將該屬性指派爲int類型便可。EF Code First會自動識別出這個字段就是表格裏的主鍵,而且會加上自動編號的識別規格設置。
當但願使用其餘域名看成主鍵時,就可能遇到一些麻煩。能夠加上key屬性(Attriute),引用System.ComponentModel.DataAnnotations命名空間。
using System; using System.ComponentModel.DataAnnotations; namespace MvcGuestbook.Models { public class Guestbook { [Key] public int No { get; set; } public string Name { get; set; } } }
(2)聲明必填字段
聲明爲string的屬性,在數據庫表格裏的字段設置爲NOT NULL。若是須要改成必填字段,能夠加上Required屬性,引用System.ComponentModel.DataAnnotations命名空間。
using System; using System.ComponentModel.DataAnnotations; namespace MvcGuestbook.Models { public class Guestbook { [Key] public int No { get; set; } [Required] public string Name { get; set; } } }
(3)聲明容許NULL字段
聲明爲DateTime的屬性,在數據庫表格裏的字段設置爲NOT NULL。若是須要改變容許爲空字段,能夠加上一個問號,不須要引用任何命名空間。
using System; using System.ComponentModel.DataAnnotations; namespace MvcGuestbook.Models { public class Guestbook { [Key] public int No { get; set; } [Required] public string Name { get; set; } public string Emai { get; set; } [Required] public string Message { get; set; } public DateTime? CreatedOn { get; set; } } }
(4)聲明字段長度
咱們也常常會在數據庫中限定特定字段的字符串長度,以方便往後建立字段索引,可使用MaxLength屬性,引用System.ComponentModel.DataAnnotations。
using System; using System.ComponentModel.DataAnnotations; namespace MvcGuestbook.Models { public class Guestbook { [Key] public int No { get; set; } [Required] [MaxLength(5)] public string Name { get; set; } [MaxLength(200)] public string Emai { get; set; } [Required] public string Message { get; set; } public DateTime? CreatedOn { get; set; } } }
也能夠設置StringLength屬性來限定字段長度。
Model類中爲屬性添加MaxLength說明,須要引用( )命名空間。
A.System.Linq B. System.ComponentModel
C. System.ComponentModel.DataAnnotations D. System.Collection.Generic
(5)聲明字段默認值
(6)聲明特定屬性不是數據庫中的字段
只要數據模型中出現公開屬性,默認就會在數據庫中建立一個對應的字段,但若是在數據模型中的屬性,是一個動態計算的屬性,咱們並不想在數據庫中新增對應的字段時,該怎麼辦?能夠加上NotMapped屬性(Attribute),引用System.ComponentModel.DataAnotations.Schema。
using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace MvcGuestbook.Models { public class Guestbook { [Key] public int No { get; set; } [Required] [MaxLength(5)] public string Name { get; set; } [MaxLength(200)] public string Emai { get; set; } [Required] public string Message { get; set; } [DatabaseGenerated(DatabaseGeneratedOption.Computed)] public DateTime? CreatedOn { get; set; } [NotMapped] public string FamilyName { get { return this.Name.Substring(0, 1); } set { this.Name = value.Substring(0, 1) + this.Name.Substring(1); } } } }
使用EF Code First在模型中聲明特定屬性不是數據庫中的字段,應使用( )關鍵字。
A.Key B.Required C.DisplayName D.NotMapped
(7)DisplayFormat
獲取數據字段的顯示格式。例如可用於設置日期的格式。
(8)DataType
獲取與數據字段關聯的類型。例如DataType.Date。
(9)DatabaseGeneratedOption
DatabaeGeneratedOption.Computed,計算列
DatabaseGeneratedOption.Identity,標識自動加1
DatabaseGeneratedOption.None,沒有標識,不自動加1
(10)Column
將類與數據庫中的表相關。 [Column(「FirstName」)]public string FirstMidName{get;set;}
2.建立數據上下文類
數據上下文類,在Entity Framework Code First開發模式下很是重要,主要用來追蹤與識別對象的變動追蹤。少了這個類別,Entity Framework就徹底沒法運做。
自動添加數據上下文類,能夠在添加控制器時操做。
public class MvcGuestbookContext : DbContext { public MvcGuestbookContext() : base("name=DefaultConnection") { } public DbSet<Guestbook> Guestbooks { get; set; } }
構造函數中的DefaultConnection爲鏈接字符串的名字,這個鏈接字符串必須存儲在web.config中。DbSet<Guest>類型的Guestbooks變量,表明的是Guestbook這個類型的數據庫集合對象。
若是但願將Guestbook數據模型被聲明成只讀,不讓應用程序對其寫入任何數據,那麼能夠修改數據上下文類,讓DbSet集合屬性只提供get實體。
public class MvcGuestbookContext : DbContext { public MvcGuestbookContext() : base("name=DefaultConnection") { } public DbSet<Guestbook> Guestbooks { get { return Set<Guestbook>(); } } }
3.設計模型之間的關聯性
在設計數據庫結構時,當遇到表格與表格間有關聯存在時,通常會經過建立外鍵(Foreign Key)的方式設計表格之間的關聯關係。
(1)設計模型之間的一對多關聯
public class Guestbook { [Key] public int No { get; set; } [Required] [MaxLength(5)] public string Name { get; set; } [MaxLength(200)] public string Emai { get; set; } [Required] public string Message { get; set; } public virtual Member Member { get; set; } }
public class Member { public int Id { get; set; } [Required] [MaxLength(5)] public string Username { get; set; } [MaxLength(10)] public string Password { get; set; } public DateTime? LastLoginTime { get; set; }
public virtual ICollection<Guestbook> Guestbooks { get; set; } }
(2)設計模型之間的多對多關聯
將上述代碼中的public virtual Member Member { get; set;},更改成:
public virtual ICollection<Member> Members { get; set; }
4.啓用延遲裝入特性
使用ORM框架,基本上都會添加「延遲裝入」的特性支持,Entity Framework固然也不例外。當使用Entit Framework的ObjectContext與DbContext操做數據時,默認都啓用「延遲裝入」。也就是當咱們在應用程序裏經過LINQ to Entity查詢數據時,若是遇到關聯數據還沒有裝入的狀況,Entity Framework會自動幫咱們再向數據庫索取關聯數據,全自動地取得關聯數據,大幅下降編寫訪問關聯數據的程序代碼。
若要在Code First模型類別中啓用「延遲裝入」特性,必須在屬性聲明時加上virtual關鍵詞。
>>導航屬性?
它是實體類上的可選屬性,它容許從關聯的一端導航到另外一端。與其餘屬性不一樣,導航屬性並不攜帶數據。