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来解决数据库更新的问题。

  1. 打开Package Manager Console

  1. 连续输入如下指令:

    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.

  2. 配置Seed方法

使用drop and re-create的方式时,因为每次model改变时数据库都会被删除,所有数据都会丢失,所以需要使用DALàAccountInitilizer.cs的Seed方法来插入测试数据。

使用Code First Migrations方式,当数据库改变时测试数据会保留,所以包含test data的Seed方法一般来说是不需要的。

如果我们要部署数据库到生产环境,事实上这种情况下我们也不想Seed方法来插入测试数据到生产环境中。

生产环境中用到Seed方法的例子: 比如在我们部署时获得了实际的初始化数据,如实际存在的组织部门这些初始化的信息。

我们为了做实验方便,还是插入一些测试数据。

先插入SysUser和SysRole

类似于前面文章提到的,Seed方法接收一个database context参数,利用这个参数添加新的实体到数据库中。

对每个实体类型:

  1. 新建一个实体集合
  2. 添加到相应的DbSet属性
  3. 保存更改到数据库中

如果大家还记得之前的文章可以发现有一点不同,以前都是用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数据迁移 转的更多相关文章

  1. Code First 数据迁移 转

    一.为模型更改设置 Code First 数据迁移 1.工具—>库程序包管理器—>程序包管理器控制台—>输入“Enable-Migrations”  或者 Enable-Migrat ...

  2. 解决 MVC4 Code First 数据迁移 数据库发生更改导致调试失败解决方法(二)

    文章转载自:http://www.cnblogs.com/amoniyibeizi/p/4486617.html 前几天学MVC过程中,遇到更改Model类以后,运行程序就会出现数据已更改的问题导致调 ...

  3. EF Code First 数据迁移配置

    这里我想讲清楚code first 数据迁移的两种模式,还有开发环境和生产环境数据迁移的最佳实践. 1.1 数据迁移综述 EF Code first 虽然已经有了几种不同的数据库初始化策略,但是大部分 ...

  4. 图文详解 解决 MVC4 Code First 数据迁移

    在使用Code first生成数据库后 当数据库发生更改时 运行程序就会出现数据已更改的问题  这时可以删除数据库重新生成解决 但是之前的数据就无法保留  为了保留之前的数据库数据  我们需要使用到C ...

  5. C#+EntityFramework编程方式详细之Code First 数据迁移

    在前几篇的C#+EntityFramework编程方式中介绍了C#+EntityFramework编程方式Code First ,Model First以及Dtatabase First 等编程方式, ...

  6. Code first 数据迁移

    前段时间用到了EF,整理一下 EF ,全称Entity FramWork.就是微软以ADO.NET为基础发展的所谓ORM(对象关系映射框架,或者说是数据持久化框架). 简单说就是根据实体对象操作数据库 ...

  7. EF6:编写你自己的code first 数据迁移操作(睡前来一篇,翻译的)

    原英文版由EF团队成员 Rowan Miller 在2013年发表,此处只作翻译备忘. 数据迁移提供了一套强类型API,用于执行通用的操作,比如CreateIndex("dbo.Blogs& ...

  8. EF Code First 数据迁移操作

    打开执行命令窗体 1.EF Code First创建数据库 PM> Install-Package EntityFramework 2.EF Code First数据库迁移 2.1.生成数据库 ...

  9. MVC 使用EF Code First数据迁移之添加字段

    PM> add-migration 20161109   -Force 正在为迁移“20161109”搭建基架.此迁移文件的设计器代码包含当前 Code First 模型的快照.在下一次搭建迁移 ...

随机推荐

  1. Kotlin语法(其他)

    三.其他 [TOC] 1. 多重声明 有时候可以通过给对象插入多个成员函数做区别是很方便的: val (name, age) = person 多重声明一次创建了多个变量.我们声明了俩个新变量:nam ...

  2. Android使用Fragment来实现ViewPager的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信

    以下内容为原创,转载请注明:http://www.cnblogs.com/tiantianbyconan/p/3364728.html 我前两天写过一篇博客<Android使用Fragment来 ...

  3. Navicat Premium11.0.20破解版快速安装配置(附文件)

    Navicat Premium是当下非常好用的数据库管理软件,但是价格非常昂贵,并且还有某些小bug,感觉3000+的人民币 与软件本身的价值还是不相称.下面是破解安装流程安装过程是在MAC 10.1 ...

  4. VC方法调用顺序

    VC1,push VC2  vc2 pop 到vc1  右滑一半,然后取消 vc1 present到vc2  vc2 dismiss到vc1  push和present是不同的.表现在两个vc ...

  5. iOS之属性修饰符 retain、strong和copy区别测试

    时不时会有点迷惑属性修饰符retain.strong.copy三者之间的区别,还是把测试过程记录下来好一点! 1.属性修饰符结论 2.给retain.strong.copy修饰的字符串属性赋值指针变化 ...

  6. 获取设备IMEI ,手机名称,系统SDK版本号,系统版本号

    1.获取设备IMEI TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); Str ...

  7. 【CoreData】分页查询和模糊查询

    在CoreData实际使用中,分页查询和模糊查询是必不可少的,接下来演示一下: 首先 // 1.创建模型文件 (相当于一个数据库里的表) // New File ———— CoreData ———— ...

  8. 关于 python

    关于python的版本: python2.7  和 python3.0 有很大的不同,学习时应因目的而做出选择. 目前用到的python2.7最多, 而web3.0时代 则用到的python3.0 所 ...

  9. XCLNetTools1.0(ASP.NET常用类库)

    版权声明:本文为博主原创文章,未经博主允许不得转载. 2016-01-01开放所有源代码: 项目地址:https://github.com/xucongli1989/XCLNetTools 下载地址: ...

  10. Java 文档注释

    Java只是三种注释方式.前两种分别是// 和/* */,第三种被称作说明注释,它以/** 开始,以 */结束. 说明注释允许你在程序中嵌入关于程序的信息.你可以使用javadoc工具软件来生成信息, ...