注:本文面向的是已经对EF的迁移功能有所了解,知道如何在控制台下进行相关命令输入的读者

问题


最近公司项目架构使用ABP进行整改,顺带想用EF的自动迁移代替了以前的手工脚本。

为什么要替代?

请看下图:

大版本就不用说了,每个小版本的发布我们都要准备一堆数据库升级脚本,这简直就是恶梦。

而使用ef它会自动帮我们完成数据库迁移,而我们只需要维护好迁移脚本就行了。

由于我们是线下项目,并且还有很多客户在使用老版本,所以我们不得不考虑既存表的问题。

而针对已存在的数据库,我们进行迁移时,总会出现Table_XXX已存在的问题,

这个很容易理解,因为就算是已存在的数据库

只要没有__migrationhistory表,它都会认为是一个新库而执行创建脚本

第二个问题是公司需要对某些功能模块进行单独迭代和发布,说简单点就是以插件包的方式安装某些功能。

用过Orchard的朋友肯定知道它的模块化机制能够单独创建和维护属于自己部分的表,

没错,我们现在就是要实现类似的功能。

解决方案


1,对已存在的数据库的迁移

对待已存在的数据库的升级该怎么办?

其实很简单,选择当前的最新的一个发布版本作为一个EF迁移初始版本,所有到初始版本的数据库升级或则全新安装都使用DDL脚本进行。

选择好最新的发布版本后,我们使用

Add-Migration Initial

来创建一个初始化迁移脚本。

然后删除Up和Down方法体中的所有内容,如下:

然后就可以开始当前迭代的开发了,在DbContext修改完毕后,我们可以使用

Add-Migration XXXXXX_X.X.X(能够描述当前版本的名字)

来创建一个当前开发版本的迁移脚本,如下。

接下来要做的就是在初始化程序时让程序自动升级,

我所知道的能做这件事办法有:

1,通过官网发布的migrate.exe来执行迁移命令。

2,通过编程控制迁移。

3,通过nuget控制台执行Update-Database。

作为一个线下项目,第三种办法显然没法使用了,而第一种需要带上exe还要写些脚本,麻烦。

第二种办法有两个类可以实现:

1,DbMigrator

            var dbMigrator = new System.Data.Entity.Migrations.DbMigrator(new Migrations.Configuration());
dbMigrator.Update();

2,MigrateDatabaseToLatestVersion

new MigrateDatabaseToLatestVersion<CoreServiceDbContext, Configuration>().InitializeDatabase(new CoreServiceDbContext());

不同之处是,前者可以选择更新的版本,后者如其名,在没有特别需求的情况下,任选其一即可。

上面的代码放在程序初始化的时候做就可以了,使用了ABP框架的朋友可以放在Data模块的PreInitialize做这件事。

或者放在global的application_start事件也不错。

这样就解决了对已存在的数据库进行自动升级的问题。

2,模块化数据迁移。

这个问题其实很好解决,每个模块配置自己的EF迁移设置时使用不同的ContextKey即可,如下:

(这是主业务功能的迁移设置)

(某模块的)

整体安装之后的迁移表如下:

可以看出各个模块都有不同的ContextKey且迁移记录都互不影响。

唯一有点遗憾是,由于我们使用Mysql并不支持DDL的事务管理,导致我们不得不在安装时手动拷贝整个数据库来以实现备份。

如果在SQLServer的环境下使用迁移的话,EF是会自动开启事务的,Oracle不太了解,有验证过的朋友麻烦留言告诉一声。

使用EF对已存在的数据库进行模块化数据迁移的更多相关文章

  1. 阿里云RDS实例内不同数据库之间的数据迁移

    适用场景 本文适用于使用DTS实现相同实例下库名不同的数据库之间的数据迁移.本文以使用DTS将同一RDS实例下的amptest库迁移到jiangliu_amptest库为例来说明如何使用DTS实现相同 ...

  2. .NET 5/.NET Core使用EF Core 5连接MySQL数据库写入/读取数据示例教程

    本文首发于<.NET 5/.NET Core使用EF Core 5(Entity Framework Core)连接MySQL数据库写入/读取数据示例教程> 前言 在.NET Core/. ...

  3. Code First Migrations更新数据库结构(数据迁移)

    背景 code first起初当修改model后,要持久化至数据库中时,总要把原数据库给删除掉再创建 (DropCreateDatabaseIfModelChanges),此时就会产生一个问题,当我们 ...

  4. ASP.NET MVC4 新手入门教程特别篇之一----Code First Migrations更新数据库结构(数据迁移)修改Entity FrameWork 数据结构(不删除数据)

    背景 code first起初当修改model后,要持久化至数据库中时,总要把原数据库给删除掉再创建(DropCreateDatabaseIfModelChanges),此时就会产生一个问题,当我们的 ...

  5. Code First Migrations更新数据库结构(数据迁移) 【转】

    注意:一旦正常后,每次数据库有变化,做如下两步: 1. Enable-Migrations 2.update-database 背景 code first起初当修改model后,要持久化至数据库中时, ...

  6. 使用Code first 进行更新数据库结构(数据迁移)

    CodeFirst 背景  code first起初当修改model后,要持久化至数据库中时,总要把原数据库给删除掉再创建(DropCreateDatabaseIfModelChanges),此时就会 ...

  7. CoreData 数据库更新,数据迁移

    本文转载至 http://blog.163.com/djx421@126/blog/static/48855136201411381212985/   一般程序app升级时,数据库有可能发生改变,如增 ...

  8. EF 中 Code First 的数据迁移以及创建视图

    写在前面: EF 中 Code First 的数据迁移网上有很多资料,我这份并没什么特别.Code First 创建视图网上也有很多资料,但好像很麻烦,而且亲测好像是无效的方法(可能是我太笨,没搞成功 ...

  9. EF Core 小技巧:迁移已经应用到数据库,如何进行迁移回退操作?

    场景描述:项目中存在两个迁移 Teacher 和 TeachingPlan ,TeachingPlan 在 Teacher 之后创建,并且已经执行 dotnet ef database update ...

随机推荐

  1. 201521123110《Java程序设计》第10周学习总结

    1. 本周学习总结 2. 书面作业 1.finally 1.1 截图你的提交结果(出现学号) 1.2 4-2中finally中捕获异常需要注意什么? finally块中的代码在正常情况下一定会执行,所 ...

  2. Hibernate第三篇【主配置文件、映射文件、复合主键映射】

    前言 目前已经学了如何搭建Hibernate的开发环境,以及Hibernate对应的API了-在快速入门还没讲解的就是配置文件是怎么配置的.因此,本博文主要讲解主配置文件以及映射配置文件.. 主配置文 ...

  3. jquery-post get 同步问题

    解决方法1: 在全局设置: $.ajaxSetup({ async : false }); 然后再使用get.post请求 $.get("register/RegisterState&quo ...

  4. Apache Spark 2.2.0 中文文档 - 快速入门 | ApacheCN

    快速入门 使用 Spark Shell 进行交互式分析 基础 Dataset 上的更多操作 缓存 独立的应用 快速跳转 本教程提供了如何使用 Spark 的快速入门介绍.首先通过运行 Spark 交互 ...

  5. FastDFS安装步骤

    FastDFS是用c语言编写的一款开源的分布式文件系统,充分考虑了冗余备份.负载均衡.线性扩容等机制,并注重高可用.高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传.下 ...

  6. iOS开发者的管理工具-CocoaPods安装

    1. 安装 Ruby 对于iOS开发者,CocoaPods是最方便使用的第三方管理工具了,但是怎么安装CocoaPods呢,安装CocoaPods之前,要确保mac已经安装上Ruby,但在安装Ruby ...

  7. css预处理器less和scss之sass介绍(二)

    本来打算整理jQuery Mobile来着,但是没有研究明白,所以接着上个周的继续介绍... [scss中的基础语法]   1.scss中的变量 ①声明变量:$变量名:变量值 $width:100px ...

  8. 西邮linux兴趣小组2014纳新免试题(四)

    [第四关] 题目 http://findakey.sinaapp.com/ Example: String1:FFFF8 5080D D0807 9CBFC E4A04 24BC6 6C840 49B ...

  9. Maven 整合strut与Hibernate,获取不到Session

    struts使用的是2.3.24 Hibernate使用的5.0.7 注意hebernate一定要在struts之前申明,不然容易出现500错误, <project xmlns="ht ...

  10. PHP中isset和empty的区别(最后总结)

    PHP的isset()函数 一般用来检测变量是否设置 格式:bool isset ( mixed var [, mixed var [, ...]] ) 功能:检测变量是否设置 返回值: 若变量不存在 ...