文中用到的工具已经开源,欢迎点Star
https://github.com/vincywindy/EntityFrameworkCore.DBCopygithub.com有时候会遇到不同数据库之前的迁移同步,这是个很大的问题,市面上有很多同步迁移工具,但是不同数据库之间类型同步是一个大的问题,比如同样的bool,Sql server 默认使用bit来存储,而Mysql,Postgresql使用Boolean来存储,这使得用来查询的sql语句不同,
Sqlserver 是
select * from xxx where isxxx=1
Mysql是
select * from xxx where isxxx=true
本身EntityFramework是解决了这个问题的,因为你不需要写rawsql,所有的sql都是由EF去生成的,所以如果你使用ef去连接数据库,那么用ef去复制迁移数据库是再好不过了。
原理
原理很简单,假设要从A数据库迁移到B数据库,那么就要从A数据库->EF读取实体->实体插入B数据库,原理那么简单,但是很多问题需要解决。
排坑
- 首先第一个问题就是阴影属性的问题,官方有文档解释
简单理解就是,当你实体里面有一些字段没有显式声明的时候,EF会创建一个隐式的属性,最常见的就是用来声明外键的id,比如你有个User和Book
public class User
{
public virtual string UserName {
get; set; }
public virtual List<Book> Books {
get; set; }
}
public class Book
{
}
这里Book里面会隐式创建一个UserId外键用来关联User,但是没写,所以EF把它创建成为了隐式属性。我们迁移的构思是数据库A->EF实体->数据库B,那么因为实体里面没有这个UserId,所以迁移到数据库B的时候,这个UserId实际上是被丢失了!因此我们需要把所有的阴影属性都显示的声明,但是实体太多了,不可能一个一个找吧,所以需要借助代码把它们都找出来,代码很简单,就一行。
context.Model.GetEntityTypes().Where(d => !d.IsAbstract()).SelectMany(d