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. Atitit.url 汉字中文路径  404 resin4 resin  解决  v2 q329

    Atitit.url 汉字中文路径  404 resin4 resin  解决  v2 q329 1. Pluginx机制1 2. Code1 3. 参考4 1. 原理 过滤器  ,,拦截jpg  w ...

  2. Android Testing学习01 介绍 测试测什么 测试的类型

    Android Testing学习01 介绍 测试测什么 测试的类型 Android 测试 测什么 1.Activity的生命周期事件 应该测试Activity的生命周期事件处理. 如果你的Activ ...

  3. 你真的了解UIApplication吗?

    一:首先查看一下关于UIApplication的定义 NS_CLASS_AVAILABLE_IOS(2_0) @interface UIApplication : UIResponder //获得单例 ...

  4. 【代码笔记】iOS-禁止输入表情符号

    一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController ...

  5. js 判断多个一样的name

    var items = document.getElementsByName("spec_spec_1[]"); alert(items.length); for (i = 0; ...

  6. win10_x64更新错误解决: 安装一些更新时出现问题,但我们稍后会重试。如果持续出现这些问题,并且你想要搜索Web或联系支持人员以获取相关信息,以下信息可能会对你有帮助:

    可能的原因: 1.windows 服务没打开 win+r,打开[运行]对话框 输入 [service.msc] 找到 [Windows Firewall]和[Internet connection s ...

  7. IntelliJ IDEA 使用Git怎样记住密码和忘记密码的方法

    IntelliJ IDEA 使用Git怎样记住密码的方法 1.当使用Ctrl+T进行更新时,弹出密码框(此时不要输入任何字符),直接点"Cancel" 2.略等二三秒,会弹出新的密 ...

  8. .net C# 图片转Base64 Base64转图片

    //图片 转为 base64编码的文本 private void button1_Click(object sender, EventArgs e) { OpenFileDialog dlg = ne ...

  9. Asp.net Mvc 多级控制器 路由重写 及 多级Views目录 的寻找视图的规则 (多级路由) 如:Admin/Test/Index

    http://blog.csdn.net/buhuan123/article/details/26387427 目录(?)[-] 1那么我们再来看我们需要的访问方式如下图 razor视图的地址写成通配 ...

  10. Cygwin VS MinGW

    首先MingW和cygwin都可以用来跨平台开发.  MinGW是Minimalistic GNU for Windows的缩写,也就是Win版的GCC.  Cygwin则是全面模拟了Linux的接口 ...