数据库迁移服务(DbMigrationService)使用文档
2026/8/12大约 3 分钟
数据库迁移服务(DbMigrationService)使用文档
ZR.ServiceCore/SqlSugar/DbMigrationService.cs 是项目的显式数据库迁移引擎。 它不扫描程序集,只迁移 SystemEntityTypes 数组中显式注册的类型,保证迁移行为可预测、可审计。
1. 核心设计
| 特性 | 说明 |
|---|---|
| 显式注册 | 新增表只需在 SystemEntityTypes 数组加一行 typeof(YourEntity) |
| 幂等 | 不删列、不改已有列类型/长度,避免破坏存量数据 |
| 单实体容错 | 某个实体迁移失败不影响其他实体,失败项记入报告 |
| 多环境 | 兼容 SQL Server / MySQL(长文本、TenantId 列按 DbType 选类型) |
| 可审计 | 每次迁移写入 __db_migration_history 表,支持 ReportOnly 预览 |
2. 三种使用方式
2.1 CLI 初始化(推荐,部署/首次建库)
dotnet run --project ZR.Admin.WebApi -- --initdb
# 或简写
dotnet run --project ZR.Admin.WebApi -- -i
命中 --initdb 后,Program.cs 会执行 InitTable.RunInitDb 完成「全量迁移 + 种子数据」后直接退出,不启动 Web 服务。 日志打印完整迁移报告,失败则 Environment.Exit(1)。
仓库根目录的
init-run.bat已封装该命令(初始化后pause防止窗口一闪而过)。
2.2 Web 启动时的存量库补列(自动,无阻塞)
SqlsugarSetup.AddDb 在所有环境启动时自动调用:
DbMigrationService.MigrateTenantColumns(); // 为已存在的表补齐 TenantId 列
此举仅兜底存量库(新装库由 CodeFirst 自动建列),幂等、不影响启动速度。
2.3 前端"同步结构"页面(在线预览/执行)
DbSyncController 调用 DbMigrationService.Migrate(mainDb) 返回变更报告,供前端展示 新增表/列清单并执行 DDL。
3. 配置项(appsettings.json → DbMigration)
"DbMigration": {
"ReportOnly": false, // true = 只对比差异、不执行 DDL(预览模式)
"AdditionalTypes": [] // 反射扩展通道,当前为空;业务模块实体改由各自 ITenantModuleInitializer 注册
}
| 配置 | 默认值 | 作用 |
|---|---|---|
ReportOnly | false | true 时只输出"将变更什么",不实际改库,用于上线前评审 |
AdditionalTypes | [] | 字符串程序集限定名数组,运行时反射加载额外实体(已清空,保留为扩展位) |
模块级开关:
InitMall/InitWorkflow/InitSaasMenu控制各业务模块是否纳入--initdb的种子/建表,由ModuleInitRunner.RunEnabledModules消费,与迁移注册表相互独立。
4. 新增一张表的标准流程
- 在业务层定义实体(带
[SugarTable("xxx")]与[SugarColumn]标注)。 - 核心/系统实体:在
DbMigrationService.SystemEntityTypes加一行typeof(YourEntity)。- 商城、工作流等业务模块实体:不要加进
SystemEntityTypes(核心层不可反向依赖业务层), 而是在对应ITenantModuleInitializer(如MallTenantInitializer/WorkflowTenantInitializer) 的InitCore中调用DbMigrationService.EnsureEntitySchema(db, typeof(YourEntity))。
- 商城、工作流等业务模块实体:不要加进
- 字符串字段务必标注长度或
[SugarColumn(ColumnDataType = "text")]/ CodeFirst_BigString, 否则兜底为varchar(255)。 - 运行
dotnet run --project ZR.Admin.WebApi -- --initdb完成建表。 - 需要唯一约束时不要依赖
[SugarIndex](本项目迁移不读该特性),改为业务层前置查重。
5. 迁移报告说明
每次 Migrate 结束打印:
========== 数据库迁移报告 ==========
--- 新增表 (2) ---
+ sys_xxx
--- 新增列 (3) ---
[sys_xxx]
+ NewCol1
+ NewCol2
迁移成功: 新增 2 表, 3 列
====================================
- 若某实体 DDL 失败,显示
--- DDL 失败 ---并列出实体名与错误,但迁移整体标记为"部分成功"。 - 历史记录写入
__db_migration_history(含 BatchId、Summary、Details JSON、AppliedAt)。
6. 关键 API 速查
| 方法 | 用途 |
|---|---|
Migrate(SqlSugarScope) | 全量 CodeFirst 迁移(建表+补列),返回报告,可选 ReportOnly |
Diff(SqlSugarScope) | 仅计算实体 vs 库结构差异,不执行 DDL,返回 MigrationReport |
EnsureEntitySchema(ISqlSugarClient, Type) | 单实体幂等建表/补列,供业务模块 initializer 调用 |
MigrateTenantColumns() | 启动时补齐存量表 TenantId 列 |
GetDbSchema(...) / GetDbSchemaForConnection(...) | 获取库表/列快照,供差异预览 |
7. 注意事项
- 不会删列、不会改列类型:已存在列的结构变更需手动
ALTER,迁移引擎只增不减。 - 长文本:
CodeFirst_BigString会自动按当前 DbType 选varchar(max)/longtext/text。 - NOT NULL 无默认值补列:存量数据冲突会导致该列补列失败,错误记入报告,需人工处理。
- Oracle 分支:类型映射已预留
VARCHAR2(64)/clob,但项目实际仅用 SQL Server / MySQL。
