zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    spring获取webapplicationcontext,applicationcontext几种方法详解(转)
    spring注入是否会被回收
    think in java 手记(一)
    spring 注解实例
    navicat远程连接oracle
    tomcat监听activemq jms配置
    HDU 1160:FatMouse's Speed
    YTU 2457: 很简单的一道题
    YTU 2456: 评委打分
    YTU 2455: Pefect 数字
  • 原文地址:https://www.cnblogs.com/qianj/p/12504702.html
Copyright © 2011-2022 走看看