MVC-05 Model(1)
??? 在開(kāi)發(fā)應(yīng)用程序的過(guò)程中,經(jīng)常需要處理許多大大小小的數(shù)據(jù),例如,SQL Server數(shù)據(jù)庫(kù)存取、連接AD(Active Directory)數(shù)據(jù)庫(kù)進(jìn)行驗(yàn)證、調(diào)用外部Web Service取得數(shù)據(jù)等。除了訪問(wèn)數(shù)據(jù)外,也經(jīng)常需要對(duì)數(shù)據(jù)做成格式驗(yàn)證、邏輯驗(yàn)證等等。
?一、Model的責(zé)任
??? 在ASP.NET MVC中,Model負(fù)責(zé)所有與“數(shù)據(jù)”有關(guān)的任務(wù)。所以,不管是Controller或是View,都會(huì)參考到Model里定義的所有數(shù)據(jù)類(lèi)型,或是用到Model里定義的一些數(shù)據(jù)操作方法,例如,新增、刪除、更改、查詢(xún)等。
??? 在Model里的程序,由于“只能”跟數(shù)據(jù)域商業(yè)邏輯有關(guān),所以就不負(fù)責(zé)處理所有與數(shù)據(jù)處理無(wú)關(guān)的事,或是用來(lái)控制網(wǎng)站的運(yùn)行流程等,而是專(zhuān)注于如何有效率地提供數(shù)據(jù)訪問(wèn)機(jī)制、交易環(huán)境、數(shù)據(jù)格式驗(yàn)證、商業(yè)邏輯驗(yàn)證等工作。
??? 由于Model的獨(dú)立性非常高,如果你在一個(gè)Visual Studio方案中,有多個(gè)要開(kāi)發(fā)的項(xiàng)目,比如有時(shí)我們會(huì)將Model獨(dú)立成一個(gè)項(xiàng)目,讓Model項(xiàng)目共享于不同的項(xiàng)目之間。
二、開(kāi)發(fā)Model的基本觀念
??? 當(dāng)采用ASP.NET MVC框架時(shí),雖然在Model層的開(kāi)發(fā)技術(shù)繁多,而且ASP.NET MVC也保留了許多彈性,讓各個(gè)不同的數(shù)據(jù)訪問(wèn)技術(shù)都能跟ASP.NET MVC集成。不過(guò),若要充分發(fā)揮ASP.NET MVC快速開(kāi)發(fā)的優(yōu)勢(shì),還是建議讀者在Model層采用ORM信息訪問(wèn)技術(shù)來(lái)開(kāi)發(fā),例如,LINQ to SQL、Entity Framework、NHibernate、Telerik OpenAccess ORM等。
1.何謂ORM
??? ORM的全名是Object Relational Mapping,中文翻譯為“對(duì)象關(guān)系映射”,是一種編程技術(shù),用于實(shí)現(xiàn)面向?qū)ο蟪绦蛘Z(yǔ)言里,不同類(lèi)型系統(tǒng)之間的數(shù)據(jù)轉(zhuǎn)換。通常在實(shí)務(wù)的應(yīng)用上,大多數(shù)情況都會(huì)應(yīng)用在數(shù)據(jù)庫(kù)與面向?qū)ο蟪绦蜃詸z的類(lèi)型轉(zhuǎn)換,例如,SQL Server中的關(guān)系型數(shù)據(jù)與.NET類(lèi)型對(duì)象之間的轉(zhuǎn)換等。
??? 換句話說(shuō),ORM是將結(jié)構(gòu)化的關(guān)系型數(shù)據(jù),映射成面向?qū)ο竽P汀?/span>如果以Entity Framework來(lái)說(shuō),就是試圖將關(guān)系數(shù)據(jù)庫(kù)的各種數(shù)據(jù)轉(zhuǎn)換成.NET原生對(duì)象,或是將.NET模型類(lèi)對(duì)象數(shù)據(jù)轉(zhuǎn)換成關(guān)系型數(shù)據(jù)。
??? 使用ORM開(kāi)發(fā)技術(shù)跟常規(guī)使用ADO.NET開(kāi)發(fā)技術(shù)最大的差異,就在于操作“數(shù)據(jù)”的方便性與彈性。以往在使用ADO.NET開(kāi)發(fā)數(shù)據(jù)訪問(wèn)程序時(shí),開(kāi)發(fā)人員通常必須先了解完整的數(shù)據(jù)庫(kù)操作方法,才能順利地從數(shù)據(jù)庫(kù)取得數(shù)據(jù),或是將對(duì)象的數(shù)據(jù)保存到數(shù)據(jù)庫(kù)中。例如,要編寫(xiě)操作SQL Server數(shù)據(jù)庫(kù)中的數(shù)據(jù),就必須先學(xué)習(xí)T-SQL的使用方式;若要操作Oracle數(shù)據(jù)庫(kù)中的數(shù)據(jù),也必須先學(xué)習(xí)Oracle的SQL查詢(xún)語(yǔ)法。學(xué)會(huì)之后還要學(xué)習(xí)各式ADO.NET的標(biāo)準(zhǔn)API,才能知道如何正確地與數(shù)據(jù)庫(kù)交互,明白是要進(jìn)行查詢(xún)數(shù)據(jù)、更新數(shù)據(jù)、新增數(shù)據(jù)還是刪除數(shù)據(jù)等。不同的數(shù)據(jù)庫(kù),在設(shè)計(jì)邏輯與SQL語(yǔ)法上都會(huì)有些小差異,而導(dǎo)致開(kāi)發(fā)數(shù)據(jù)訪問(wèn)的程序代碼缺乏效率。如此一來(lái),也有違“關(guān)注點(diǎn)分離”的特性,若是套用“關(guān)注點(diǎn)分離”特性,照理說(shuō)在開(kāi)發(fā).NET應(yīng)用程序時(shí),應(yīng)該專(zhuān)注在對(duì)象的操作上,而非數(shù)據(jù)庫(kù)數(shù)據(jù)的處理,當(dāng)采用ORM開(kāi)發(fā)技術(shù)后,便可以幫助我們達(dá)到這個(gè)目的。
??? Entity Framwork是建構(gòu)在ADO.NET數(shù)據(jù)提供者模型之上,也就是說(shuō),只要.NET運(yùn)行環(huán)境能夠使用ADO.NET連接數(shù)據(jù)庫(kù),Enity Framework便能順利支持,在.NET運(yùn)行環(huán)境下默認(rèn)已經(jīng)支持SQL Server 2005以上版本,如果要支持其他如Oracle、MySQL、SQLite、PostgreSQL等各式各樣的關(guān)系數(shù)據(jù)庫(kù)基本上也是沒(méi)問(wèn)題的,只要操作出相對(duì)應(yīng)的Entity Framework數(shù)據(jù)提供者即可。
2.數(shù)據(jù)庫(kù)開(kāi)發(fā)模式
??? 采用Entity Framework或其他ORM開(kāi)發(fā)極速,有時(shí)還可區(qū)分三種不同的開(kāi)發(fā)模式,分別是數(shù)據(jù)庫(kù)優(yōu)先開(kāi)發(fā)模式(Database First Development)、模型優(yōu)先開(kāi)發(fā)模式(Model First Development)、程序代碼優(yōu)先開(kāi)發(fā)模式(Code First Development)。
(1)數(shù)據(jù)庫(kù)優(yōu)先開(kāi)發(fā)模式
??? 顧名思義,數(shù)據(jù)庫(kù)優(yōu)先開(kāi)發(fā)模式就是針對(duì)數(shù)據(jù)庫(kù)進(jìn)行設(shè)計(jì),以數(shù)據(jù)庫(kù)里定義的數(shù)據(jù)結(jié)構(gòu)(Schema)為主。當(dāng)應(yīng)用程序在卡法的時(shí)候,必須依據(jù)數(shù)據(jù)庫(kù)的結(jié)構(gòu)設(shè)計(jì)來(lái)進(jìn)行開(kāi)發(fā),使用的ORM框架必須能夠依據(jù)數(shù)據(jù)庫(kù)結(jié)構(gòu)設(shè)計(jì)生成相應(yīng)的對(duì)象模型,才能提供給應(yīng)用程序來(lái)使用。
(2)模型優(yōu)先開(kāi)發(fā)模式
??? 模型優(yōu)先開(kāi)發(fā)模式是指在ORM架構(gòu)中創(chuàng)建對(duì)象模型,讓?xiě)?yīng)用程序能夠依據(jù)這些對(duì)象模型進(jìn)行開(kāi)發(fā)。需要實(shí)際訪問(wèn)數(shù)據(jù)庫(kù)時(shí),只要通過(guò)Entity Framework數(shù)據(jù)提供者的協(xié)助,動(dòng)態(tài)生成相應(yīng)的SQL語(yǔ)法,即可創(chuàng)建出完整的數(shù)據(jù)庫(kù)。
??? 一般來(lái)說(shuō),支持模型優(yōu)先開(kāi)發(fā)模式的ORM框架,都會(huì)有相對(duì)應(yīng)的程序代碼生成技術(shù),在模型被創(chuàng)建的同時(shí)自動(dòng)生成相對(duì)應(yīng)的程序代碼。以Entity Framework為例,在搭配Visual Studio的幫助下,即可通過(guò)Entity Framework設(shè)計(jì)工具,幫你創(chuàng)建對(duì)象模型,只要保存后,就會(huì)自動(dòng)生成相關(guān)程序代碼。
(3)程序代碼優(yōu)先開(kāi)發(fā)模式
??? 程序代碼優(yōu)先開(kāi)發(fā)模式是一種非常新穎的開(kāi)發(fā)模式,也就是讓開(kāi)發(fā)人員直接依據(jù)需求,編寫(xiě)類(lèi)別與屬性(程序代碼),而這些撰寫(xiě)的類(lèi)別與屬性正是定義出應(yīng)用程序所需的數(shù)據(jù)模型,并且通過(guò)ORM框架的管理,便可讓這些POCO類(lèi)型,轉(zhuǎn)換成實(shí)體模型(Entity Model)。
??? 直到程序開(kāi)始運(yùn)行后,通過(guò)ORM框架,就可以自動(dòng)依據(jù)這些類(lèi)別,定義創(chuàng)建數(shù)據(jù)庫(kù)、表格、字段與其他數(shù)據(jù)結(jié)構(gòu)(Schema)。這樣開(kāi)發(fā)人員便可以完全不需要接觸數(shù)據(jù)庫(kù)這一端的各種管理工作(如創(chuàng)建表格字段、設(shè)計(jì)數(shù)據(jù)表、設(shè)計(jì)數(shù)據(jù)表關(guān)聯(lián)等),也不用學(xué)習(xí)各式數(shù)據(jù)庫(kù)的使用差異(如SQL Server、Oracle、MySQL、SQLite等),省去這些工作之后,開(kāi)發(fā)人員更能專(zhuān)注在應(yīng)用程序的需求開(kāi)發(fā),而不會(huì)因?yàn)椴皇煜?shù)據(jù)庫(kù)操作而束手束腳。
三、LocalDB介紹
??? 微軟最新推出的SQL Server 2012 Express LocalDB,是一種SQL Server Express的運(yùn)行模式,特別適合在開(kāi)發(fā)環(huán)境使用,也內(nèi)建在Visual Studio 2012之中。
1.LocalDB的運(yùn)作方式
??? 在安裝好SQL Server 2012 Express LocalDB之后,默認(rèn)會(huì)有個(gè)實(shí)例名,為v11.0。
2.如何連接LocalDB實(shí)例
(1)使用Management Studio連接LocalDB
??? 在連接對(duì)話框中輸入正確服務(wù)器名稱(chēng),(localdb)\v11.0。只有新版的SQL Server 2012 Management Studio才能識(shí)別這組新的服務(wù)器名稱(chēng)。
(2)通過(guò).NET程序連接LocalDB實(shí)例
??? 連接字符串如下。
Server=(LocalDB)\v11.0; Integrated Security=true; AttachDbFileName=D:\Data\MyDB1.mdf3.管理LocalDB自動(dòng)實(shí)例
4.管理LocalDB具名實(shí)例
四、使用Code First創(chuàng)建數(shù)據(jù)模型
??? ASP.NET MVC4與當(dāng)前最新版的Entity Framework 5同時(shí)上市,尤其強(qiáng)化了程序代碼優(yōu)先開(kāi)發(fā)模式的支持。
1.創(chuàng)建數(shù)據(jù)模型
(1)聲明主鍵
??? 要想在Entity Framework聲明主鍵,最簡(jiǎn)單的方式就是不要聲明,直接把屬性名稱(chēng)設(shè)置為Id或是類(lèi)名+“Id”也可以,并將該屬性指派為int類(lèi)型即可。EF Code First會(huì)自動(dòng)識(shí)別出這個(gè)字段就是表格里的主鍵,并且會(huì)加上自動(dòng)編號(hào)的識(shí)別規(guī)格設(shè)置。
???? 當(dāng)希望使用其他域名當(dāng)作主鍵時(shí),就可能遇到一些麻煩。可以加上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的屬性,在數(shù)據(jù)庫(kù)表格里的字段設(shè)置為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的屬性,在數(shù)據(jù)庫(kù)表格里的字段設(shè)置為NOT NULL。如果需要改變?cè)试S為空字段,可以加上一個(gè)問(wèn)號(hào),不需要引用任何命名空間。
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)聲明字段長(zhǎng)度
??? 我們也經(jīng)常會(huì)在數(shù)據(jù)庫(kù)中限定特定字段的字符串長(zhǎng)度,以方便日后創(chuàng)建字段索引,可以使用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; }} }??? 也可以設(shè)置StringLength屬性來(lái)限定字段長(zhǎng)度。
Model類(lèi)中為屬性添加MaxLength說(shuō)明,需要引用(?? ?)命名空間。
A.System.Linq???????????????????????????? B. System.ComponentModel
C. System.ComponentModel.DataAnnotations? D. System.Collection.Generic
(5)聲明字段默認(rèn)值
(6)聲明特定屬性不是數(shù)據(jù)庫(kù)中的字段
??? 只要數(shù)據(jù)模型中出現(xiàn)公開(kāi)屬性,默認(rèn)就會(huì)在數(shù)據(jù)庫(kù)中創(chuàng)建一個(gè)對(duì)應(yīng)的字段,但如果在數(shù)據(jù)模型中的屬性,是一個(gè)動(dòng)態(tài)計(jì)算的屬性,我們并不想在數(shù)據(jù)庫(kù)中新增對(duì)應(yīng)的字段時(shí),該怎么辦?可以加上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在模型中聲明特定屬性不是數(shù)據(jù)庫(kù)中的字段,應(yīng)使用(? )關(guān)鍵字。
A.Key??? B.Required??? C.DisplayName??? D.NotMapped
(7)DisplayFormat
獲取數(shù)據(jù)字段的顯示格式。例如可用于設(shè)置日期的格式。
(8)DataType
獲取與數(shù)據(jù)字段關(guān)聯(lián)的類(lèi)型。例如DataType.Date。
(9)DatabaseGeneratedOption
DatabaeGeneratedOption.Computed,計(jì)算列
DatabaseGeneratedOption.Identity,標(biāo)識(shí)自動(dòng)加1
DatabaseGeneratedOption.None,沒(méi)有標(biāo)識(shí),不自動(dòng)加1
(10)Column
將類(lèi)與數(shù)據(jù)庫(kù)中的表相關(guān)。?[Column(“FirstName”)]public string FirstMidName{get;set;}
2.創(chuàng)建數(shù)據(jù)上下文類(lèi)
????數(shù)據(jù)上下文類(lèi),在Entity Framework Code First開(kāi)發(fā)模式下非常重要,主要用來(lái)追蹤與識(shí)別對(duì)象的變更追蹤。少了這個(gè)類(lèi)別,Entity Framework就完全無(wú)法運(yùn)作。
??? 自動(dòng)添加數(shù)據(jù)上下文類(lèi),可以在添加控制器時(shí)操作。
public class MvcGuestbookContext : DbContext{public MvcGuestbookContext(): base("name=DefaultConnection"){}public DbSet<Guestbook> Guestbooks { get; set; }}??? 構(gòu)造函數(shù)中的DefaultConnection為連接字符串的名字,這個(gè)連接字符串必須存儲(chǔ)在web.config中。DbSet<Guest>類(lèi)型的Guestbooks變量,代表的是Guestbook這個(gè)類(lèi)型的數(shù)據(jù)庫(kù)集合對(duì)象。
??? 如果希望將Guestbook數(shù)據(jù)模型被聲明成只讀,不讓?xiě)?yīng)用程序?qū)ζ鋵?xiě)入任何數(shù)據(jù),那么可以修改數(shù)據(jù)上下文類(lèi),讓DbSet集合屬性只提供get實(shí)體。
public class MvcGuestbookContext : DbContext{public MvcGuestbookContext(): base("name=DefaultConnection"){}public DbSet<Guestbook> Guestbooks{get { return Set<Guestbook>(); }}}?
3.設(shè)計(jì)模型之間的關(guān)聯(lián)性
??? 在設(shè)計(jì)數(shù)據(jù)庫(kù)結(jié)構(gòu)時(shí),當(dāng)遇到表格與表格間有關(guān)聯(lián)存在時(shí),一般會(huì)通過(guò)創(chuàng)建外鍵(Foreign Key)的方式設(shè)計(jì)表格之間的關(guān)聯(lián)關(guān)系。
(1)設(shè)計(jì)模型之間的一對(duì)多關(guān)聯(lián)
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)設(shè)計(jì)模型之間的多對(duì)多關(guān)聯(lián)
??? 將上述代碼中的public virtual Member Member { get; set;},更改為:
public virtual ICollection<Member> Members { get; set; }4.啟用延遲裝入特性
??? 使用ORM框架,基本上都會(huì)添加“延遲裝入”的特性支持,Entity Framework當(dāng)然也不例外。當(dāng)使用Entit Framework的ObjectContext與DbContext操作數(shù)據(jù)時(shí),默認(rèn)都啟用“延遲裝入”。也就是當(dāng)我們?cè)趹?yīng)用程序里通過(guò)LINQ to Entity查詢(xún)數(shù)據(jù)時(shí),如果遇到關(guān)聯(lián)數(shù)據(jù)尚未裝入的情況,Entity Framework會(huì)自動(dòng)幫我們?cè)傧驍?shù)據(jù)庫(kù)索取關(guān)聯(lián)數(shù)據(jù),全自動(dòng)地取得關(guān)聯(lián)數(shù)據(jù),大幅降低編寫(xiě)訪問(wèn)關(guān)聯(lián)數(shù)據(jù)的程序代碼。
??? 若要在Code First模型類(lèi)別中啟用“延遲裝入”特性,必須在屬性聲明時(shí)加上virtual關(guān)鍵詞。
??? >>導(dǎo)航屬性?
??? 它是實(shí)體類(lèi)上的可選屬性,它允許從關(guān)聯(lián)的一端導(dǎo)航到另一端。與其他屬性不同,導(dǎo)航屬性并不攜帶數(shù)據(jù)。
轉(zhuǎn)載于:https://www.cnblogs.com/meetyy/p/3474092.html
總結(jié)
以上是生活随笔為你收集整理的MVC-05 Model(1)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 十六进制颜色值对照表
- 下一篇: sencha touch 手势识别左右滑