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 ...
随机推荐
- 【php】 jsonp转数组函数jsonp_decode
分享一个可以跟json一样用的函数jsonp_decode,能把jsonp格式数据转为php数组或对象. /** * 把jsonp转为php数组 * @param string $jsonp js ...
- Tensorflow从0到1(3)之实战传统机器算法
计算图中的操作 import numpy as np import tensorflow as tf sess = tf.Session() x_vals = np.array([1., 3., 5. ...
- LR字符串处理函数-lr_save_string
int lr_save_string( const char *param_value, const char *param_name) 指定字符串保存至参数 Action() { lr_save_s ...
- 研为电子6轴运动控制卡win10驱动无法安装问题,解决方法
研为电子6轴运动控制卡win10驱动无法安装问题,解决方法 研为电子6轴运动控制卡win10驱动无法安装问题,解决方法 iMC3xx2E系列运动控制卡使用手册V1.003 IMCdrv_Ins.exe ...
- 【Spring注解驱动开发】如何使用@Bean注解指定初始化和销毁的方法?看这一篇就够了!!
写在前面 在[String注解驱动开发专题]中,前面的文章我们主要讲了有关于如何向Spring容器中注册bean的知识,大家可以到[String注解驱动开发专题]中系统学习.接下来,我们继续肝Spri ...
- 【Spring注解驱动开发】使用InitializingBean和DisposableBean来管理bean的生命周期,你真的了解吗?
写在前面 在<[Spring注解驱动开发]如何使用@Bean注解指定初始化和销毁的方法?看这一篇就够了!!>一文中,我们讲述了如何使用@Bean注解来指定bean初始化和销毁的方法.具体的 ...
- npm设置为淘宝镜像地址
1. npm设置为淘宝镜像 $npm config set registry https://registry.npm.taobao.org 2. 检查一下 $npm config get regis ...
- 13.DRF-版本
Django rest framework源码分析(4)----版本 版本 新建一个工程Myproject和一个app名为api (1)api/models.py from django.db imp ...
- v-on事件修饰符
.stop阻止冒泡 .prevent阻止默认行为 .capture实现捕获触发事件的机制(从大到小) .self实现只有点击当前元素时,才能出发事件处理函数 .once只触发一次事件函数 .stop和 ...
- 05、MyBatis 缓存
1.MyBatis缓存 MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制.缓存可以极大的提升查询效率. 1).一级缓存 public Employee getEmpById( ...
