MVC+EF6教程四:不丢失数据进行数据库结构升级 文章提纲 前置条件 启用迁移 执行迁移 总结
本篇文章我们会使用 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配置节注释掉。
另外我们不用原来数据,改下数据库名(MvcDemo改为MvcDemo2),这样可以生成一个新的数据库,方便做实验。
<add name="AccountContext" connectionString="Data Source=.;database=MvcDemo2;uid=sa;pwd=123456;AttachDBFilename=|DataDirectory|MvcDemo2.mdf;" providerName="System.Data.SqlClient" />
启用迁移
下面就启用Code First Migrations来解决数据库更新的问题。
打开Package Manager Console,连续输入enable-migrations 和 add-migration InitialCreate命令
enable-migrations指令:
a.在项目根目录下自动创建了一个Migrations文件夹
b.在Migrations文件夹下自动新建一个Configuration.cs文件。
如果前面没修改web.config的数据库名, 执行enable-migrations指令后,Migrations将会找到已有的数据库MVCDemo然后自动执行add-migration指令
执行迁移
前面执行 add-migration时,同样在Migrations文件夹里面,产生一个<timestamp>_InitialCreate.cs的文件。
里面两个方法,Up和Down:
Up方法创建数据库表,Down方法删除表。
public partial class InitialCreate : DbMigration { 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(), Password = c.String(), Email = 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方法来填充测试数据。
这个时候打开数据库看下,完全符合我们的预期。
再进一步,我们添加一个表Organize,先添加一个Model
public class Organize { public int ID { get; set; } /// <summary> /// 组织名称 /// </summary> public int OrganizeName { get; set; } }
修改AccountContext.cs, 增加一个data model entity set
执行add-migration AddTestTable和update-database, 完成数据库表的添加。
去数据库中检查,发现已经多了Organize这张表了
添加表之后,我发现表Organize少加了一个字段ParentID,字段OrganizeName的类型需要修改为字符串类型,修改Organize实体类
/// <summary> /// 组织名称 /// </summary> public string OrganizeName { get; set; } /// <summary> /// 上级组织ID /// </summary> public int ParentID { get; set; }
执行add-migration AddTestTable和update-database, 完成数据库表的修改。
最后再检查下新产生的配置文件
public override void Up() { AddColumn("dbo.Organize", "ParentID", c => c.Int(nullable: false)); AlterColumn("dbo.Organize", "OrganizeName", c => c.String()); } public override void Down() { AlterColumn("dbo.Organize", "OrganizeName", c => c.Int(nullable: false)); DropColumn("dbo.Organize", "ParentID"); }
总结
本次我们主要讲解了数据库迁移/升级的问题。
主要分为 启用迁移(enable-migrations) 和 执行迁移(add-migration, update-database) 两大步骤。
启用迁移:产生迁移相关文件夹Migrations和文件夹中相关的配置文件。
执行迁移:产生相关的迁移更改文件并执行更改。
权责申明
作者:编程小纸条 出处: https://www.cnblogs.com/miro/category/620362.html