MVC-05 Model(2)
五、使用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)的更多相关文章
- 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. ...
- 一缕阳光:DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?
写在前面 阅读目录: 问题根源是什么? <领域驱动设计-软件核心复杂性应对之道>分层概念 Repository(仓储)职责所在? Domain Model(领域模型)重新设计 Domain ...
- DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?
DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)? 阅读目录: 问题根源是什么? <领域驱动设计-软件核心复杂性应对之道>分层概念 Repositor ...
- 死去活来,而不变质:Domain Model(领域模型) 和 EntityFramework 如何正确进行对象关系映射?
写在前面 阅读目录: 设计误区 数据库已死 枚举映射 关联映射 后记 在上一篇<一缕阳光:DDD(领域驱动设计)应对具体业务场景,如何聚焦 Domain Model(领域模型)?>博文中, ...
- [译]MVC网站教程(三):动态布局和站点管理
目录 1. 介绍 2. 软件环境 3. 在运行示例代码之前(源代码 + 示例登陆帐号) 4. 自定义操作结果和控制器扩展 1) OpenFileResult 2) ImageR ...
- [译]MVC网站教程(二):异常管理
介绍 “MVC网站教程”系列的目的是教你如何使用 ASP.NET MVC 创建一个基本的.可扩展的网站. 1) MVC网站教程(一):多语言网站框架 2) MVC网站教程(二):异常管理 3) ...
- [译]MVC网站教程(一):多语言网站框架
本文简介 本博文介绍了 Visual Studio 工具生成的 ASP.NET MVC3 站点的基本框架:怎样实现网站的语言的国际化与本地化功能,从零开始实现用户身份认证机制,从零开始实现用户注册机制 ...
- 【Spring MVC系列】--(4)返回JSON
[Spring MVC系列]--(4)返回JSON 摘要:本文主要介绍如何在控制器中将数据生成JSON格式并返回 1.导入包 (1)spring mvc 3.0不需要任何其他配置,添加一个jackso ...
- DDD(领域驱动设计)应对具体业务场景,Domain Model(领域模型)到底如何设计?
DDD(领域驱动设计)应对具体业务场景,Domain Model(领域模型)到底如何设计? 写在前面 阅读目录: 迷雾森林 找回自我 开源地址 后记 毫无疑问,领域驱动设计的核心是领域模型,领域模型的 ...
- Domain Model(领域模型) 和 EntityFramework 如何正确进行对象关系映射?
Domain Model(领域模型) 和 EntityFramework 如何正确进行对象关系映射? 写在前面 阅读目录: 设计误区 数据库已死 枚举映射 关联映射 后记 在上一篇<一缕阳光:D ...
随机推荐
- C++_基础_类和对象2
内容: (1)构造函数 (2)初始化列表及其必要性 (3)支持自定义类型转换的构造函数 (4)this指针 (5)const对象和成员函数 (6)析构函数 1.构造函数1.1 格式: class 类名 ...
- [MAC Eclipse] Eclipse for MAC 中文乱码的解决办法
笔者将在windows下的eclipse写的代码拷贝到MAC下,发现中文会出现乱码. 最初笔者遇到这个问题的时候,在网络上寻找了解决办法,出来的第一个网页(http://blog.csdn.net/w ...
- (转) ios学习之 关于Certificate、Provisioning Profile、App ID的介绍及其之间的关系
刚接触iOS开发的人难免会对苹果的各种证书.配置文件等不甚了解,可能你按照网上的教程一步一步的成功申请了真机调试,但是还是对其中的缘由一知半解.这篇文章就对Certificate.Provisioni ...
- while和for可以相互转换例子
//while和for循环可以相互转换,以下为简单格式: ;;) A; 等价于 : ) { A; ; } /* Name:while和for可以相互转换例子 Copyright: By.不懂网络 Au ...
- 配置Raspbian 启用SPI I2C
sudo vi /etc/modprobe.d/raspi-blacklist.conf 找到这两行 blacklist spi-bcm2708 blacklist i2c-bcm2708 注释掉 # ...
- for循环产生的Cortex-M3汇编代码的一个奇怪现象
最近比较一下KEIL和IAR两个编译器产生的代码,基于Cortex-M3处理器的,然后发现了一几个奇怪的地方. 很简单的一个C的for循环 void fun_for_add_65535(void) { ...
- InnerException 消息是“反序列化对象 属于类型 *** 时出现错误。读取 XML 数据时,超出最大字符串内容长度配额 (8192)。(注意细节)
WEB站点在调用我们WCF服务的时候,只要传入的参数过长,就报如下错误: 格式化程序尝试对消息反序列化时引发异常: 尝试对参数 http://tempuri.org/ 进行反序列化时出错: formD ...
- PHPRPC for PHP
14的路 PHPRPC for PHP PHPRPC 是一个轻型的.安全的.跨网际的.跨语言的.跨平台的.跨环境的.跨域的.支持复杂对象传输的.支持引用参数传递的.支持内容输出重定向的.支持分级错误处 ...
- C++STL之string (转)
在学习c++STL中的string,在这里做个笔记,以供自己以后翻阅和初学者参考. 1:string对象的定义和初始化以及读写 string s1; 默认构造函数,s1为空串 string ...
- FPGA STA(静态时序分析)
1 FPGA设计过程中所遇到的路径有输入到触发器,触发器到触发器,触发器到输出,例如以下图所看到的: 这些路径与输入延时输出延时,建立和保持时序有关. 2. 应用背景 静态时序分析简称STA,它是一种 ...