注:本文面向的是已经对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. 201521123113《Java程序设计》第12周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对象(属性:int id, String name,int age,doubl ...

  2. panda库2

    >>> a=pd.Series([1,2],index=['a','b']) >>> a a 1 b 2 dtype: int64 >>> b=p ...

  3. LCA问题第二弹

    LCA问题第二弹 上次用二分的方法给大家分享了对 LCA 问题的处理,各位应该还能回忆起来上次的方法是由子节点向根节点(自下而上)的处理,平时我们遇到的很多问题都是正向思维处理困难而逆向思维处理比较容 ...

  4. RG_5

    必须发博纪念经过昨天的开车, 作业本终于做完啦!!! 可以认真的刷题了.

  5. 策略模式Strategy

    定义一系列的算法,把他们封装起来,使得算法独立于适用对象. 比如,一个系统有很多的排序算法,但是使用哪个排序算法是客户对象的自有.因此把每一个排序当做一个策略对象,客户调用哪个对象,就使用对应的策略方 ...

  6. uva12519

    The Farnsworth Parabox Professor Farnsworth, a renowned scientist that lives in year 3000 working at ...

  7. Java课堂作业01

    题目:编写一个程序,此程序从命令行接收多个数字,求和之后输出结果. 设计思想:用for循环将string型转换为int型,再用sum求和,使其一直相加,到达最大长度,sum即为所求sum. 程序流程图 ...

  8. 五年.net程序员转型Java之路

    大学毕业后笔者进入一家外企,做企业CRM系统开发,那时候开发效率最高的高级程序语言,毫无疑问是C#.恰逢公司也在扩张,招聘了不少.net程序员,笔者作为应届生,也乐呵呵的加入到.net程序员行列中. ...

  9. 在Java环境上运行redis

    首先你得有Java环境,不多说,参考http://jingyan.baidu.com/article/f96699bb8b38e0894e3c1bef.html 下载redis驱动包 链接:http: ...

  10. PHP计算上个月的开始时间和结束时间戳

    $m = date('Y-m-d', mktime(0,0,0,date('m')-1,1,date('Y'))); $t = date('t',strtotime($m)); //上个月共多少天 $ ...