五、使用Code First数据库迁移

当Entity Framework Code First的数据模型发生异动时,默认会引发一个System.InvalidOpertaionException异常。一种解决方法是在Global.asax文档里的Application_Sart方法上,加上一段System.Data.Entity.Database.SetInitializer()方法,让EF自动将数据库删除,然后重新创建模型。不过,这种将数据库砍掉重建的方式实在过于残暴,应该使用更人性化的方式,让EF帮助我们自动调整数据库架构,并且仍然保留现有数据库中的数据。而这种开发技术就是Code First数据库迁移(DB Migration)。

Code First数据库迁移技术,在EF4.3.1版本之后才支持。

System.Data.Entity.Database.SetInitializer(
new System.Data.Entity.DropCreateDatabaseIfModelChanges<MvcGuestbook.Models.MvcGuestbookContext>());

System.Data.Entity.DropCreateDatabaseIfModelChanges方法的作用是在Model发生改变时,会运行Drop和Create Database  
等动作。

EF Code First数据库迁移的方法。

  • Enable-Migrations
  • Add-Migration Initial
  • Update-Database

1. EF Code First如何记录版本
2. 启用数据库迁移

若要在项目中启用数据库迁移功能,必须先开启程序包管理器控制台(Package Manager Console)窗格,然后输入Enable-Migrations指令。

我们在使用EF进行数据库迁移时,需要用到vs集成开发环境里的工具(   )进行迁移。

A.程序包可视化工具    B.NuGet工具    C.程序包管理器控制台    D.工具箱

按下Enter键后,Packae Manager Console会自动扫描这个项目中所有的数据上下文类。如果一个项目中有一个以上的数据类别,就会出现错误,必须选用其中一个来启用数据库迁移功能。

PM> Enable-Migrations -ContextTypeName MvcGuestbook.Models.MvcGuestbookContext

运行Enable-Migrations指令的过程中,VS2012会帮助我们在指定的项目里创建一个Migrations目录,该目录下还创建有两个重要的文档,一个是*_InitialCreate.cs文档,另一个是Configuration.cs文档。
(1)*_InitialCreate.cs

(2)Configuration.cs

例,通过Configuration.cs里的Seed方法插入网站初始留言数据。

var messages = new List<Message>

{ new Message {Title="Hello to my space",Author="Admin"},

new Message {Title="This is my second time to be here",Author="Admin"},

new Message {Title="Is there anybody can help me",Author="Mike"}

};

messages.ForEach(m => context.Messages.AddOrUpdate(p => p.Title, m));

context.SaveChanges();

3.运行数据库迁移

我们通过Package Manager Console输入Add-Migration指令,来新增一条数据库迁移版本,输入时必须带上一个“版本名称”参数。例如,要想取名为AddUsernamePassword,则可以输入以下指令:

PM> Add-Migration AddUsernamePassword

运行Add-Migration指令,所代表的意思就是新增一次运行数据库迁移命令,VS2012会自动对比当前数据库中的Model定义与当前更改过的数据模型,并将差异的字段变化写入这个自动新增的类别内。
    每一次新增数据库迁移版本,其类别内都会包含一个Up()方法与Down()方法,所代表的意思分别是“升级数据库”与“降级数据库”的动作,所以数据库迁移不仅仅是将数据库升级,还可以恢复到旧版本。

接着我们正式对数据库进行迁移动作。

PM> Update-Database

4.自定义数据库迁移规则

5.自动数据库迁移

Enable-Migrations –EnableAutomaticMigration

对于实体插入操作,直接使用Update-Database

对于实体更新和删除操作,使用

Add-Migration Initial

Update-Database

6.如何避免数据库被自动创建或自动迁移

7.获取Sql脚本

  • Update-Database –Script
  • Update-Database –Script –SourceMigration:$InitialDatabase –TargetMigration: AddPostAbstract

8. 迁移到特定版本

Update-Database –TargetMigration:ad1

Update-Database –TargetMigration:$InitialDatabase

六、使用ViewModel数据视图模型

在此所自定义的数据模型并不是要决定数据“如何呈现”,而是决定“有哪些数据要呈现”在View上。所以,在View中应该决定的是数据呈现的方式,如HTML、Silverlight等,而在Model中所定义的却是“有哪些字段应该显示在界面上”,这算是商业逻辑的一部分。

在Model层定义的数据模型会运用在整个项目里,无论是由Controller进行信息操作(CRUD),还是在View里面参考Modl层定义的数据模型都会用到。不过,毕竟Model层创建数据模型时,主要是以数据为中心来定义,并不一定适用所有View层的要求。

以会员信息为例,同一个Member数据模型,在会员注册时输入的字段可能是Username、Password、Name、Email,等等,而且每个字段都设置为必填。而同样用到Member数据名,在开发会员登录窗体时,却只要输入Username与Password即可,在登录页面是不用输入Name与Email字段的,因此,若你在会员登录窗体使用Member数据模型进行参考时,就会导致进行数据模型绑定(Model Binding)时发生字段验证失败的问题,此时就需要使用额外定义的ViewModel当作会员登录窗体的数据模型。

这类专门提供给View使用的数据模型,通常称为数据视图模型(ViewModel)。

七、扩充数据模型

1.定义数据模型的Metadata

2.自定义Metadata验证属性

3.ASP.NET MVC 3新增的验证属性

在System.Web.Mvc命名空间下。

(1)Compare,用来比对数据模型中另一个字段是否与套用的字段一致。此属性可用在需要输入两次密码的窗体上,也就是在会员注册页面时,可能会需要输入两次相同的面,避免使用者的输入错误。

(2)Remote,将该字段输入值通过Ajax送到指定的Action做验证,通过远程验证后回传的结果,当作验证的成功与否。此属性可用在验证用户输入的会员账号是否已被使用,通过远程Ajax调用可提升窗体输入的使用性(Usability)。

4.Entity Framework 4 新增的验证属性

在System.ComponentModel.DataAnnotations命名空间下,不过却要添加EntityFramework.dll组件参考才会有。

(1)MinLength,用来验证该资源输入数据的最少字数。此属性可用在密码输入字段,限制使用者至少输入几位数以上的密码,或是输入用户账号时至少输入多少字数以上。

(2)MaxLength,用来验证该字段输入信息的最多字数,此属性与StringLength属性的用法完全相同。

5. .NET4.5新增的验证属性

MembershipPasswordAttribute,验证密码字段是否符合成员资格提供者当前的密码需求。此属性可用在密码输入字段,通过Membership提供者所定义的密码复杂度要求进行检查。在System.Web.Security命名空间中。

MVC-05 Model(2)的更多相关文章

  1. 008.Adding a model to an ASP.NET Core MVC app --【在 asp.net core mvc 中添加一个model (模型)】

    Adding a model to an ASP.NET Core MVC app在 asp.net core mvc 中添加一个model (模型)2017-3-30 8 分钟阅读时长 本文内容1. ...

  2. 一缕阳光:DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?

    写在前面 阅读目录: 问题根源是什么? <领域驱动设计-软件核心复杂性应对之道>分层概念 Repository(仓储)职责所在? Domain Model(领域模型)重新设计 Domain ...

  3. DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?

    DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)? 阅读目录: 问题根源是什么? <领域驱动设计-软件核心复杂性应对之道>分层概念 Repositor ...

  4. 死去活来,而不变质:Domain Model(领域模型) 和 EntityFramework 如何正确进行对象关系映射?

    写在前面 阅读目录: 设计误区 数据库已死 枚举映射 关联映射 后记 在上一篇<一缕阳光:DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?>博文中, ...

  5. [译]MVC网站教程(三):动态布局和站点管理

    目录 1.   介绍 2.   软件环境 3.   在运行示例代码之前(源代码 + 示例登陆帐号) 4.   自定义操作结果和控制器扩展 1)   OpenFileResult 2)   ImageR ...

  6. [译]MVC网站教程(二):异常管理

    介绍 “MVC网站教程”系列的目的是教你如何使用 ASP.NET MVC 创建一个基本的.可扩展的网站. 1)   MVC网站教程(一):多语言网站框架 2)   MVC网站教程(二):异常管理 3) ...

  7. [译]MVC网站教程(一):多语言网站框架

    本文简介 本博文介绍了 Visual Studio 工具生成的 ASP.NET MVC3 站点的基本框架:怎样实现网站的语言的国际化与本地化功能,从零开始实现用户身份认证机制,从零开始实现用户注册机制 ...

  8. 【Spring MVC系列】--(4)返回JSON

    [Spring MVC系列]--(4)返回JSON 摘要:本文主要介绍如何在控制器中将数据生成JSON格式并返回 1.导入包 (1)spring mvc 3.0不需要任何其他配置,添加一个jackso ...

  9. DDD(领域驱动设计)应对具体业务场景,Domain Model(领域模型)到底如何设计?

    DDD(领域驱动设计)应对具体业务场景,Domain Model(领域模型)到底如何设计? 写在前面 阅读目录: 迷雾森林 找回自我 开源地址 后记 毫无疑问,领域驱动设计的核心是领域模型,领域模型的 ...

  10. Domain Model(领域模型) 和 EntityFramework 如何正确进行对象关系映射?

    Domain Model(领域模型) 和 EntityFramework 如何正确进行对象关系映射? 写在前面 阅读目录: 设计误区 数据库已死 枚举映射 关联映射 后记 在上一篇<一缕阳光:D ...

随机推荐

  1. 使用 Eclipse Memory Analyzer 进行堆转储文件分析

    Eclipse Memory Analyzer(MAT)是著名的跨平台集成开发环境 Eclipse Galileo 版本的 33 个组成项目中之一,它是一个功能丰富的 JAVA 堆转储文件分析工具,可 ...

  2. 发现一个名为“Douyu”的国人项目

    刚刚在javaeye看到一个名为Douyu的国人项目,认为搞下去未来可能非常有意思,放到blog上做个标记. ——————下面是转载的作者原文——————— 原文地址例如以下:http://zhh20 ...

  3. java中关于线程间协作所用关键字synchronized,wait,notify的用法

    wait/notify()关键字适用于一个线程通知另一个线程所需的条件状态已就绪,最常用于线程在循环中休眠直到获取特定条件的场景. 例如,一个线程一直等待直到队列中有一个组件能够处理:当组件添加到队列 ...

  4. 深入理解java虚拟机系列二——垃圾收集算法

    在主流的商用程序语言中大多都是用根搜索算法(GC Roots Tracing)判断对象是否存活,比如java,c#等.当从GC Roots到某个对象不可达,则证明此对象是不可用的,将要被回收. 商业虚 ...

  5. iOS开发之C语言函数库

    在iOS开发中不可避免的需要使用数学函数进行计算,我们可以使用C标准库头文件中定义的数学常量宏及数学函数来进行基本的数学计算操作,这些C函数都可以在微软的MSDNAPI库中找到.(https://ms ...

  6. ##DAY14——StoryBoard

    •iOS下可视化编程分为两种⽅式:xib和storyboard. •在使用xib和storyboard创建GUI过程中,以XML文件格式 存储在Xcode中,编译时生成nib的二进制文件.在运行时, ...

  7. [C#参考]主线程和子线程之间的参数传递

    几个进程在大多数情况下要包含很多的子线程,那么他们之间免不了的要互相传递很多的参数,那么参数怎么传递的呢? 主线程向子线程传递参数的方法 第一种方法:Thraed类有一个带参数的委托类型的重载形式,这 ...

  8. JQuery中serialize() 序列化

    更多2014/8/24 来源:jquery学习浏览量:1671 学习标签: serialize 本文导读:在jQuery中,当我们使用ajax时,常常需要拼装input数据以键值对(Key/Value ...

  9. Class类对象的三种实例化方法

    class X { } public class GetClassDemo01 {     public static void main(String[] args) {         X x = ...

  10. netty中实现客户端首次连接绑定并非每次read检查的方法

    需求场景 客户端第一次连接时,将客户端存起来 重写 ChannelHandlerAdapter 的 handlerAdded 方法