MVC code first数据迁移 转
coptto:http://www.cnblogs.com/miro/p/4164076.html
本篇是相对独立的一篇,主要讲解不丢失数据进行数据库结构升级。
前面我们讲解EF功能时(见第三篇文章)已经介绍过一种更新数据库的方式:
EF比较model和database,如果两边不一致,程序将会drop and re-create数据库。
本篇文章我们会使用 code first migrations的方式。
这个功能可以使你改变data model,在不drop and re-create数据库的情况下更新数据库的结构,将这些改变部署到生产环境中。
下面就着重介绍如何使用此功能。
文章提纲
- 前置条件
- 启用迁移功能
- 执行迁移
- 总结
前置条件
先回顾下之前EF修改模型的方式。
我们事先配置好EF,每次数据模型改变的时候都会drop and re-create数据库。
例如你增加、删除、改变实体类,或改变DbContext类后,运行程序时将会自动删除已有的数据库,创建一个新数据库来匹配修改后的模型,同样也会根据Seed方法中内容新建test data.
这种保持database和data model同步的方法在开发阶段很方便。
如果已经部署到生产环境中就不行了, 例如表中扩充一些字段啥的, 原来的数据就不能丢失。
我们禁用原来更新数据库的方式,将web.config中contexts配置节注释掉。
另外我们不用原来数据,改下数据库名,这样可以生成一个新的数据库,方便做实验。
启用迁移
下面就启用Code First Migrations来解决数据库更新的问题。
- 打开Package Manager Console
- 连续输入如下指令:
enable-migrations 和 add-migration InitialCreate
enable-migrations指令:
a.在项目根目录下创建了一个Migrations文件夹
b.在Migrations文件夹下新建一个Configuration.cs文件。
可以通过修改Configuration.cs来对Migration做一些配置(如加入一些测试数据等)
Note
如果前面没修改web.config的数据库名, 执行enable-migrations指令后,Migrations将会找到已有的数据库MVCDemo然后自动执行add-migration指令。
类似我们第三篇文章中讲到 DALàAccountInitilizer.cs类,Configuration类也包含一个Seed方法。
当数据库新建或数据库结构更新后,这个方法会被调用,利用这个方法可以插入或更新test data.
- 配置Seed方法
使用drop and re-create的方式时,因为每次model改变时数据库都会被删除,所有数据都会丢失,所以需要使用DALàAccountInitilizer.cs的Seed方法来插入测试数据。
使用Code First Migrations方式,当数据库改变时测试数据会保留,所以包含test data的Seed方法一般来说是不需要的。
如果我们要部署数据库到生产环境,事实上这种情况下我们也不想Seed方法来插入测试数据到生产环境中。
生产环境中用到Seed方法的例子: 比如在我们部署时获得了实际的初始化数据,如实际存在的组织部门这些初始化的信息。
我们为了做实验方便,还是插入一些测试数据。
先插入SysUser和SysRole
类似于前面文章提到的,Seed方法接收一个database context参数,利用这个参数添加新的实体到数据库中。
对每个实体类型:
- 新建一个实体集合
- 添加到相应的DbSet属性
- 保存更改到数据库中
如果大家还记得之前的文章可以发现有一点不同,以前都是用Add方法,这次用了AddOrUpdate方法来插入数据。
sysUsers.ForEach(s => context.SysUsers.AddOrUpdate(p => p.UserName, s));
每次执行update-databse指令时都会执行Seed方法,一般来说,每次迁移后,你不仅仅是插入数据,例如你想要插入的数据在你创建数据库的第一次迁移后已经在数据库中了,这种情况下更新原有数据就可以了。
AddOrUpdate正好可以解决这个问题:
如果数据不存在,插入数据;如果数据存在,更新这笔数据。
context.SysUsers.AddOrUpdate(p => p.UserName, s)
第一个参数p.UserName就是检查数据是否存在的主键。
我们的测试数据中,假设UserName都不能重复。
作为比较,我们添加SysUserRole实体类型的时候没有使用AddOrUpdate,直接人为判断是否存在,不存在再插入。
编译下项目,下面开始更新数据库。
执行迁移
前面执行 add-migration时,同样在Migrations文件夹里面,产生一个<timestamp>_InitialCreate.cs的文件。
里面两个方法,Up和Down:
Up方法创建数据库表,Down方法删除表。
public override void Up()
{
CreateTable(
"dbo.SysRole",
c => new
{
ID = c.Int(nullable: false, identity: true),
RoleName = c.String(),
RoleDesc = c.String(),
})
.PrimaryKey(t => t.ID);
CreateTable(
"dbo.SysUserRole",
c => new
{
ID = c.Int(nullable: false, identity: true),
SysUserID = c.Int(nullable: false),
SysRoleID = c.Int(nullable: false),
})
.PrimaryKey(t => t.ID)
.ForeignKey("dbo.SysRole", t => t.SysRoleID, cascadeDelete: true)
.ForeignKey("dbo.SysUser", t => t.SysUserID, cascadeDelete: true)
.Index(t => t.SysUserID)
.Index(t => t.SysRoleID);
CreateTable(
"dbo.SysUser",
c => new
{
ID = c.Int(nullable: false, identity: true),
UserName = c.String(),
Email = c.String(),
Password = c.String(),
})
.PrimaryKey(t => t.ID);
}
public override void Down()
{
DropForeignKey("dbo.SysUserRole", "SysUserID", "dbo.SysUser");
DropForeignKey("dbo.SysUserRole", "SysRoleID", "dbo.SysRole");
DropIndex("dbo.SysUserRole", new[] { "SysRoleID" });
DropIndex("dbo.SysUserRole", new[] { "SysUserID" });
DropTable("dbo.SysUser");
DropTable("dbo.SysUserRole");
DropTable("dbo.SysRole");
}
下面我们就执行正式迁移。打开Package Manager Console
输入 update-database
update-database指令调用了Up方法来新建database的表(和data model entity set对应), 然后调用Seed方法来填充测试数据。
这个时候测试下程序,打开数据库看下,完全符合我们的预期。
再进一步,我们添加一个表Test
先添加一个Model
修改AccountContext.cs, 增加一个data model entity set
执行add-migration AddTestTable和update-database, 完成数据库表的添加。
去数据库中检查,发现已经多了Test这张表了。
最后再检查下新产生的配置文件。
大家现在应该能充分理解到add-migration时产生的文件的作用了吧。
MVC code first数据迁移 转的更多相关文章
- Code First 数据迁移 转
一.为模型更改设置 Code First 数据迁移 1.工具—>库程序包管理器—>程序包管理器控制台—>输入“Enable-Migrations” 或者 Enable-Migrat ...
- 解决 MVC4 Code First 数据迁移 数据库发生更改导致调试失败解决方法(二)
文章转载自:http://www.cnblogs.com/amoniyibeizi/p/4486617.html 前几天学MVC过程中,遇到更改Model类以后,运行程序就会出现数据已更改的问题导致调 ...
- EF Code First 数据迁移配置
这里我想讲清楚code first 数据迁移的两种模式,还有开发环境和生产环境数据迁移的最佳实践. 1.1 数据迁移综述 EF Code first 虽然已经有了几种不同的数据库初始化策略,但是大部分 ...
- 图文详解 解决 MVC4 Code First 数据迁移
在使用Code first生成数据库后 当数据库发生更改时 运行程序就会出现数据已更改的问题 这时可以删除数据库重新生成解决 但是之前的数据就无法保留 为了保留之前的数据库数据 我们需要使用到C ...
- C#+EntityFramework编程方式详细之Code First 数据迁移
在前几篇的C#+EntityFramework编程方式中介绍了C#+EntityFramework编程方式Code First ,Model First以及Dtatabase First 等编程方式, ...
- Code first 数据迁移
前段时间用到了EF,整理一下 EF ,全称Entity FramWork.就是微软以ADO.NET为基础发展的所谓ORM(对象关系映射框架,或者说是数据持久化框架). 简单说就是根据实体对象操作数据库 ...
- EF6:编写你自己的code first 数据迁移操作(睡前来一篇,翻译的)
原英文版由EF团队成员 Rowan Miller 在2013年发表,此处只作翻译备忘. 数据迁移提供了一套强类型API,用于执行通用的操作,比如CreateIndex("dbo.Blogs& ...
- EF Code First 数据迁移操作
打开执行命令窗体 1.EF Code First创建数据库 PM> Install-Package EntityFramework 2.EF Code First数据库迁移 2.1.生成数据库 ...
- MVC 使用EF Code First数据迁移之添加字段
PM> add-migration 20161109 -Force 正在为迁移“20161109”搭建基架.此迁移文件的设计器代码包含当前 Code First 模型的快照.在下一次搭建迁移 ...
随机推荐
- 8月7号晚7点Autodesk北京办公室,我们来聊聊HTML5/ WebGL 3D 模型浏览技术
Autodesk 发布了一款完全无需插件的三维模型浏览器 Autodesk 360 Viewer,大家有没有兴趣,下班后过来聊聊吧! 8月7号 周四, 19:00~21:00 Autodesk北京 ...
- 应用代理 socket TCP协议 的资料
http://blog.csdn.net/guowake/article/details/6615728 Linux下高并发socket最大连接数所受的各种限制 http://stackoverflo ...
- Android JNI简介
JNI简介 JNI (Java Native Interface),Java的本地接口 JNI是Java众多开发技术中的一门,意在利用本地代码,为Java程序提供 更高效,更灵活的拓展.应用场景包括: ...
- 深入.net(类及方法)
.net 的命名规则: 帕斯卡命名法 ----- 多个单词说明,且直接连接,并首字母大写(类名.方法名.属性名....) 骆驼命名法---------多个单词说明,且直接连接,并首字母大写,第一个字母 ...
- 转载文章----IL反编译利器——Ildasm.exe和Reflector.exe:
转载地址:http://www.cnblogs.com/yangmingming/archive/2010/02/03/1662546.html 一:Ildasm.exe简介 这一微软VS自带工具, ...
- ThreadLocal源码分析
1.概述 ThreadLocal,可以理解为线程的局部变量,作用就是为每一个使用该变量的线程都提供一个变量值的副本,每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突. ThreadLo ...
- Asp.net MVC使用Model Binding解除Session, Cookie等依赖
上篇文章"Asp.net MVC使用Filter解除Session, Cookie等依赖"介绍了如何使用Filter来解除对于Session, Cookie的依赖.其实这个也可以通 ...
- JavaScript Patterns 5.5 Sandbox Pattern
Drawbacks of the namespacing pattern • Reliance on a single global variable to be the application’s ...
- 深入解析Windows操作系统笔记——CH1概念和术语
1.概念和工具 本章主要介绍Windows操作系统的关键概念和术语 1.概念和工具 1.1操作系统版本 1.2基础概念和术语 1.2.1Windows API 1.2.2 服务.函数和例程 1.2.3 ...
- SQLServer修改字段类型
Alter table [表名] Alter column [列名] [列类型]