ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

abp一代数据迁解析

2020-07-07 21:08:41  阅读:457  来源: 互联网

标签:一代 租户 数据库 abp 添加 AbpZeroDbMigrator 迁移 解析


abp版本5.9

概述

数据迁移无非就是两件事情,1、创建数据库,并根据实体创建对应的表;2、添加一些初始数据

abp的数据迁移也是完成这两件事,比较特殊的是它是多租户saas系统,而且支持不同的租户有独立的数据库。所以abp中的迁移要先迁移户主Host,再迁移租户Tenant的数据库

它的迁移定义了一个架子,这个架子定义了abp数据库迁移的几个步骤,在这些步骤挖了几个坑,留给我们来自定义。

为了我们使用更方便,它还实现了一些简单的默认数据的初始化

所以我们需要先搞懂abp数据库迁移的基本原理,真正使用时我们只需要去填那几个坑就可以了。

核心步骤

  1. 创建并初始化AbpBootstrapper,有点类似Main函数的功效,只不过它是abp系统的起点。它创建依赖注入容器,并注册各abp模块,并处理它们的依赖关系和执行顺序
  2. 通过依赖注入获取MultiTenantMigrateExecuter并执行Run方法,内部逻辑如下:
    1. 通过依赖注入获取AbpZeroDbMigrator,
    2. 拿到户主(Host)的连接字符串
    3. 执行AbpZeroDbMigrator.CreateOrMigrateForHost 并传递一个委托。主要是创建户主和相应的用户角色权限等信息。我们可以在这里定义创建更多租户的逻辑
      1. 创建户主(Host)数据库和表结构
      2. 执行委托创建初始数据,其中包括户主(host)的用户角色权限等
    4. 获取上一步骤创建好的更多租户,遍历它们逐一做数据库迁移。使用AbpZeroDbMigrator.CreateOrMigrateForTenant(tenant),AbpZeroDbMigrator具体实现由我们提供,但它有抽象类,所以如果需要我们可以重写几个方法

一般情况红色字体标注部分是我们比较关心的,主要是在迁移时添加更多租户;为每个租户添加默认数据;

模板项目下载后,有个XXX.Migrator项目,它就是abp数据库迁移程序,是个控制台。只是使用的话看官方文档就可以了。下面分别说说里面的几个核心类

AbpBootstrapper

这个我没去细看,但是根据经验应该能猜到它是ABP系统的起点,初始化时会去创建全局的依赖注入容器,从入口模块开始,根据模块间的依赖最终加载所需要的所有模块,并根据依赖顺序执行模块中相应的方法。这里主要说迁移,所以不深入了,参考官方文档就可以了 abp启动配置 模块系统  。

默认情况下,创建AbpBootstrapper时是从XXXMigratorModule模块开始加载的,而它依赖[DependsOn(typeof(XXXEntityFrameworkModule))],而后者又依赖XXXCoreModule,当然这条依赖线可能会更长,具体看你的项目了。

MultiTenantMigrateExecuter

AbpBootstrapper创建并初始化后,依赖注入框架就可以使用了,且各模块也初始化好了。迁移时会从容器中取出一个MultiTenantMigrateExecuter,把它理解为多租户迁移执行器,它是在MultiTenantMigrateExecuter模块初始化时注册的。它负责上面步骤的2.1 ——2.4

它主要是用来定义迁移的大步骤,虽然我们可以来修改这里的代码,但是通常没啥必要。核心步骤就是

  1. 从容器中取得AbpZeroDbMigrator
  2. 执行AbpZeroDbMigrator.CreateOrMigrateForHost 初始化户主的数据库并添加默认数据
  3. 执行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,添加,AbpZeroDbMigrator,迁移,解析
来源: https://www.cnblogs.com/jionsoft/p/13263156.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有