abp一代数据迁解析

abp版本5.9git

概述

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

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

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

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

因此咱们须要先搞懂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数据库迁移程序,是个控制台。只是使用的话看官方文档就能够了。下面分别说说里面的几个核心类spa

AbpBootstrapper

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

默认状况下,建立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> ,它按简单方式实现了:一、租户数据库的建立和初始数据的添加;二、租户数据库的建立和初始数据的添加;数据库的建立的直接调用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),提供本身的委托来添加初始数据

相关文章
相关标签/搜索