在开发应用程序的过程当中,常常须要处理许多大大小小的数据,例如,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关键词。
>>导航属性?
它是实体类上的可选属性,它容许从关联的一端导航到另外一端。与其余属性不一样,导航属性并不携带数据。