abp一代数据迁解析
abp版本5.9
概述
数据迁移无非就是两件事情,1、创建数据库,并根据实体创建对应的表;2、添加一些初始数据
abp的数据迁移也是完成这两件事,比较特殊的是它是多租户saas系统,而且支持不同的租户有独立的数据库。所以abp中的迁移要先迁移户主Host,再迁移租户Tenant的数据库
它的迁移定义了一个架子,这个架子定义了abp数据库迁移的几个步骤,在这些步骤挖了几个坑,留给我们来自定义。
为了我们使用更方便,它还实现了一些简单的默认数据的初始化
所以我们需要先搞懂abp数据库迁移的基本原理,真正使用时我们只需要去填那几个坑就可以了。
核心步骤
- 创建并初始化AbpBootstrapper,有点类似Main函数的功效,只不过它是abp系统的起点。它创建依赖注入容器,并注册各abp模块,并处理它们的依赖关系和执行顺序
- 通过依赖注入获取MultiTenantMigrateExecuter并执行Run方法,内部逻辑如下:
- 通过依赖注入获取AbpZeroDbMigrator,
- 拿到户主(Host)的连接字符串
- 执行AbpZeroDbMigrator.CreateOrMigrateForHost 并传递一个委托。主要是创建户主和相应的用户角色权限等信息。我们可以在这里定义创建更多租户的逻辑
- 创建户主(Host)数据库和表结构
- 执行委托创建初始数据,其中包括户主(host)的用户角色权限等
- 获取上一步骤创建好的更多租户,遍历它们逐一做数据库迁移。使用AbpZeroDbMigrator.CreateOrMigrateForTenant(tenant),AbpZeroDbMigrator具体实现由我们提供,但它有抽象类,所以如果需要我们可以重写几个方法
一般情况红色字体标注部分是我们比较关心的,主要是在迁移时添加更多租户;为每个租户添加默认数据;
模板项目下载后,有个XXX.Migrator项目,它就是abp数据库迁移程序,是个控制台。只是使用的话看官方文档就可以了。下面分别说说里面的几个核心类
AbpBootstrapper
这个我没去细看,但是根据经验应该能猜到它是ABP系统的起点,初始化时会去创建全局的依赖注入容器,从入口模块开始,根据模块间的依赖最终加载所需要的所有模块,并根据依赖顺序执行模块中相应的方法。这里主要说迁移,所以不深入了,参考官方文档就可以了 abp启动配置 模块系统 。
默认情况下,创建AbpBootstrapper时是从XXXMigratorModule模块开始加载的,而它依赖[DependsOn(typeof(XXXEntityFrameworkModule))],而后者又依赖XXXCoreModule,当然这条依赖线可能会更长,具体看你的项目了。
MultiTenantMigrateExecuter
AbpBootstrapper创建并初始化后,依赖注入框架就可以使用了,且各模块也初始化好了。迁移时会从容器中取出一个MultiTenantMigrateExecuter,把它理解为多租户迁移执行器,它是在MultiTenantMigrateExecuter模块初始化时注册的。它负责上面步骤的2.1 ——2.4
它主要是用来定义迁移的大步骤,虽然我们可以来修改这里的代码,但是通常没啥必要。核心步骤就是
- 从容器中取得AbpZeroDbMigrator
- 执行AbpZeroDbMigrator.CreateOrMigrateForHost 初始化户主的数据库并添加默认数据
- 执行AbpZeroDbMigrator.CreateOrMigrateForTenant(tenant);为每一个租户创建数据库和初始数据
先不管AbpZeroDbMigrator是哪注册的,
在步骤2中执行CreateOrMigrateForHost 时丢入了一个委托SeedHelper.SeedHostDb,它默认情况下初始化Host数据库,并添加户主和默认的用户、角色、权限等数据。所以如果我们只是先在迁移时添加更多租户,可以来修改SeedHelper.SeedHostDb静态方法。
步骤3默认情况下啥都没干,但是在这个大步骤中执行了它,所以如果我们想为每个租户添加一些初始数据,我们应该提供AbpZeroDbMigrator.CreateOrMigrateForTenant(tenant);方法,具体如何做呢?往下看
AbpZeroDbMigrator
MultiTenantMigrateExecuter定义了迁移的几个大步骤,初始化Host数据库并添加默认数据;初始化租户数据库并添加默认数据;这两个任务的具体逻辑是交给AbpZeroDbMigrator来完成的
AbpZeroDbMigrator是我们提供的,定义在XXX.EntityFrameworkCore项目中,它实现IAbpZeroDbMigrator接口。它在模块的初始化方法中注册打动依赖注入容器的。
为了我们使用更简单,abp为我们提供一个抽象类AbpZeroDbMigrator<TDbContext> ,它按简单方式实现了:1、租户数据库的创建和初始数据的添加;2、租户数据库的创建和初始数据的添加;数据库的创建的直接调用DbContext.DataBase.Migrate(),这是EF提供的功能,初始数据的添加则是让调用方来提供,就是个委托,在创建数据库后会回调这个委托。
因此下载的abp项目模板中XXX.EntityFrameworkCore中定义的XXXDbMigrator继承了AbpZeroDbMigrator<TDbContext>,但却没有实现,因为父类都做好了。
到此,数据库的创建最终是efcore的Migrate方法完成的,Host户主的初始数据的添加的委托是直接由SeedHelper.SeedHostDb来提供的。租户的初始数据的添加我们可以在自己的XXXDbMigrator中重写CreateOrMigrateForTenant方法来实现,水在这个方法内我们可以通过参数拿到当前的租户,委托中的参数为我们提供了当前租户的dbContext,因此我们不用关心这个dbcontext是每个租户一个,还是各租户使用的是同一个数据库。
总结
要在数据库初始化时添加更多租户,在XXX.EntityFrameworkCore/Seed/SeedHelper中改
要为每个租户添加一些初始数据是,在XXX.EntityFrameworkCore/AbpZeroDbMigrator中重写CreateOrMigrateForTenant(AbpTenantBase tenant),然后调用父类的CreateOrMigrateForTenant(AbpTenantBase tenant, Action<TDbContext> seedAction),提供自己的委托来添加初始数据
abp一代数据迁解析的更多相关文章
- ABP使用及框架解析系列 - [Unit of Work part.1-概念及使用]
前言 ABP ABP是“ASP.NET Boilerplate Project”的简称. ABP的官方网站:http://www.aspnetboilerplate.com ABP在Github上的开 ...
- ABP使用及框架解析系列 - [Unit of Work part.2-框架实现]
前言 ABP ABP是“ASP.NET Boilerplate Project”的简称. ABP的官方网站:http://www.aspnetboilerplate.com ABP在Github上的开 ...
- NPOI操作EXCEL(三)——反射机制进行excel表格数据的解析
我们先来回忆回忆上篇文章讲到的通过xml配置文件实现excel批量模板解析的整体思路: 1.对每个excel模板制定xml配置规则集,实现xml配置文件的解析服务 2.为每个excel模板制定DTO, ...
- XML数据的解析
XML数据的解析 相比于JSON数据解析而言,XML数据解析可能会让更多的童鞋感觉到吃力,对我来说,同样认为JSON数据好像让人感觉比较友好,不过对于程序开发者来说,无非就是这两种数据解析占比较大的部 ...
- 解剖SQLSERVER 第四篇 OrcaMDF里对dates类型数据的解析(译)
解剖SQLSERVER 第四篇 OrcaMDF里对dates类型数据的解析(译) http://improve.dk/parsing-dates-in-orcamdf/ 在SQLSERVER里面有几 ...
- android基础---->JSON数据的解析
上篇博客,我们谈到了XML两种常用的解析技术,详细可以参见我的博客(android基础---->XMl数据的解析).网络传输另外一种数据格式JSON就是我们今天要讲的,它是比XML体积更小的数据 ...
- Android 之 json数据的解析(jsonReader)
json数据的解析相对而言,还是比较容易的,实现的代码也十分简单.这里用的是jsonReade方法来进行json数据解析. 1.在解析之前,大家需要知道什么是json数据. json数据存储的对象是无 ...
- Json--Android中数据文件解析(Json解析--从服务器端获取数据并且解析,显示在客户端上面)
前面学习过了使用SAX解析XML数据(点击进入:SAX解析XML数据),今天学习Json解析: 首先说一下Json数据的最基本的特点,Json数据是一系列的键值对的集合,和XML数据来比,Json数据 ...
- Android通过类对象的方式实现JSON数据的解析
1.通过主Activity的Button按钮实现数据的解析 public class MainActivity extends Activity { //定义一个包含Json格式的字符对象 priva ...
随机推荐
- Hadoop之hadoop fs和hdfs dfs、hdfs fs三者区别
适用范围 案例 备注 小记 hadoop fs 使用范围最广,对象:可任何对象 hadoop dfs 只HDFS文件系统相关 hdfs fs 只HDFS文件系统相关(包括与 ...
- zabbix 中文乱码
环境 zabbix 3.4.7 centos 7.4 问题现象 zabbix 中文乱码 解决方法 1.先准备一个字体包 Windows路径 C:\Windows\Fonts\simkai ...
- 0.大话Spring Cloud
天天说Spring cloud ,那到底它是什么? 定义 它不是云计算解决方案 它是一种微服务开发框架 它是(快速构建分布式系统的通用模式的)工具集 它基于Spring boot 构建开发 它是云原生 ...
- Spring AOP—注解配置方法的使用
Spring除了支持Schema方式配置AOP,还支持注解方式:使用@AspectJ风格的切面声明. 1 启用对@AspectJ的支持 Spring默认不支持@AspectJ风格的切面声明,为了支持需 ...
- 面试必问:分布式锁实现之zk(Zookeeper)
点赞再看,养成习惯,微信搜索[三太子敖丙]关注这个互联网苟且偷生的工具人. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的 ...
- Loadrunner12将fiddler跟踪文件转为脚本的后续处理事项
之前一篇文章说过,Loadrunner12是支持将fiddler的跟踪文件.SAZ直接转成LR的脚本的,好多小伙伴都用了这个方法,但是生成脚本后用LR11运行的时候就出问题了,会发现runtime-s ...
- flex弹性布局及其属性
CSS3 弹性盒子内容 弹性盒子由弹性容器(Flex container)和弹性子元素(Flex item)组成. 弹性容器通过设置 display 属性的值为 flex 或 inline-flex将 ...
- Windows 10 WSL 2.0安装并运行Docker
在Windows 10 2004版本,微软更新WSL到了2.0,WSL 2.0已经拥有了完整的Linux内核!今天来测试一下,是否可以安装docker! 一.开启WSL 以管理员运行Powershe ...
- Java并发编程(05):悲观锁和乐观锁机制
本文源码:GitHub·点这里 || GitEE·点这里 一.资源和加锁 1.场景描述 多线程并发访问同一个资源问题,假如线程A获取变量之后修改变量值,线程C在此时也获取变量值并且修改,两个线程同时并 ...
- 最通俗易懂的RSA加密解密指导
前言 RSA加密算法是一种非对称加密算法,简单来说,就是加密时使用一个钥匙,解密时使用另一个钥匙. 因为加密的钥匙是公开的,所又称公钥,解密的钥匙是不公开的,所以称为私钥. 密钥 关于RSA加密有很多 ...
