- 新增 MiGu.DB 项目,迁移所有领域实体与枚举,统一模型约定 - 实现 Entity/Repository/UoW/Provider/Exception 等接口与实现 - 支持数据修补机制,完善 Sqlite 初始迁移与数据库管理 - Server 侧移除 EF Core 相关,依赖 MiGu.DB,PlatformPersistence 适配 - 业务服务注入 UoW/Repository,状态字段统一用 enum 及辅助类 - 统一异常处理,Controller 映射 HTTP 状态码 - 配置项与文档补充数据库启动、SchemaMode、迁移说明 - 新增 GlobalUsings.Db.cs、WmsStatusAliases.cs 简化类型引用 - 新增 HttpActorContextMiddleware 支持操作者上下文一致性 - 新增 MiGuDbContextModelSnapshot 追踪数据库结构 - 优化代码结构,解耦领域与持久层,提升扩展性与安全性
222 lines
7.6 KiB
Markdown
222 lines
7.6 KiB
Markdown
# MiGu.DB Migrations 使用手册
|
||
|
||
面向日常改表、发版与排错。当前默认 Provider 为 **Sqlite**,迁移目录为 `Migrations/Sqlite/`。
|
||
|
||
---
|
||
|
||
## 1. 概念速览
|
||
|
||
| 概念 | 说明 |
|
||
|------|------|
|
||
| Migration | 一次 Schema 变更(建表/加列/索引等),对应一对 `*_Name.cs` + `*_Name.Designer.cs` |
|
||
| ModelSnapshot | `MiGuDbContextModelSnapshot.cs`,当前模型总快照;下次 `add` 时与代码模型做 diff |
|
||
| `__EFMigrationsHistory` | 数据库内表,记录已应用的 Migration Id |
|
||
| DataMigrator | **数据**修补(刷旧状态、回填列),不是 Schema;启动时在 Migrate 之后执行 |
|
||
|
||
**原则:Schema 只走 Migrations;业务代码禁止手写 CREATE/ALTER。**
|
||
|
||
三个文件职责:
|
||
|
||
- `YYYYMMDDHHMMSS_Name.cs` → `Up()`/`Down()`,真正改库
|
||
- `YYYYMMDDHHMMSS_Name.Designer.cs` → 该次迁移的目标模型元数据(勿手改)
|
||
- `MiGuDbContextModelSnapshot.cs` → 全库最新快照(勿手改,除非处理合并冲突)
|
||
|
||
---
|
||
|
||
## 2. 环境准备
|
||
|
||
### 2.1 工具
|
||
|
||
仓库根目录(`Migu2.0`)执行:
|
||
|
||
```powershell
|
||
# 全局工具(任选)
|
||
dotnet tool install --global dotnet-ef --version 8.0.10
|
||
|
||
# 或本地工具目录(本仓库曾用此方式)
|
||
dotnet tool install dotnet-ef --version 8.0.10 --tool-path .\.tools
|
||
.\.tools\dotnet-ef --version
|
||
```
|
||
|
||
版本需与项目 EF Core **8.0.x** 对齐。
|
||
|
||
### 2.2 工程关系
|
||
|
||
| 参数 | 值 |
|
||
|------|-----|
|
||
| 迁移所在工程 | `MiGu.DB` |
|
||
| 启动工程 | `MiGu.Server`(提供配置与 Design 包) |
|
||
| DbContext | `MiGu.DB.Kernel.Context.MiGuDbContext` |
|
||
| Design-time 工厂 | `MiGu.DB.Kernel.Design.MiGuDbContextFactory` |
|
||
|
||
`MiGu.Server.csproj` 已引用 `Microsoft.EntityFrameworkCore.Design`;`MiGu.DB` 含 Sqlite 等 Provider 包。
|
||
|
||
---
|
||
|
||
## 3. 生成 Migration(日常流程)
|
||
|
||
### 3.1 改模型
|
||
|
||
在 `MiGu.DB/Domains` 改实体或 `IEntityTypeConfiguration`,保存后编译通过:
|
||
|
||
```powershell
|
||
dotnet build .\MiGu.DB\MiGu.DB.csproj
|
||
```
|
||
|
||
### 3.2 添加迁移
|
||
|
||
在**解决方案根目录**执行(PowerShell):
|
||
|
||
```powershell
|
||
dotnet ef migrations add <迁移名称> `
|
||
--project .\MiGu.DB\MiGu.DB.csproj `
|
||
--startup-project .\MiGu.Server\MiGu.Server.csproj `
|
||
--output-dir Migrations/Sqlite `
|
||
--namespace MiGu.DB.Migrations.Sqlite `
|
||
--context MiGuDbContext
|
||
```
|
||
|
||
命名建议(PascalCase,无空格):
|
||
|
||
| 场景 | 示例名 |
|
||
|------|--------|
|
||
| 首库 | `InitialPlatform`(已存在,勿重复) |
|
||
| 加表 | `AddWmsXxxTable` |
|
||
| 加列 | `AddStoragePriorityColumn` |
|
||
| 加索引 | `AddStockEventOperatedAtIndex` |
|
||
|
||
### 3.3 生成后检查(必做)
|
||
|
||
1. 新文件应在:`MiGu.DB/Migrations/Sqlite/`
|
||
2. 打开 `*_Name.cs`,确认 `Up()` 只包含**本次预期**变更(无误删表、无多余重建)
|
||
3. 确认 `MiGuDbContextModelSnapshot.cs` 仍在 `Migrations/Sqlite/`
|
||
- 若出现在 `MiGu.DB/MiGu/DB/Migrations/Sqlite/` 等错误路径:把 Snapshot **移回**正确目录并删掉空目录(`--namespace` 偶发路径问题)
|
||
|
||
### 3.4 应用到本地库
|
||
|
||
启动 `MiGu.Server` 即可(`EnsurePlatformDatabaseAsync` → `MigrateMiGuDbAsync`),或:
|
||
|
||
```powershell
|
||
dotnet ef database update `
|
||
--project .\MiGu.DB\MiGu.DB.csproj `
|
||
--startup-project .\MiGu.Server\MiGu.Server.csproj `
|
||
--context MiGuDbContext
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 常用命令
|
||
|
||
```powershell
|
||
# 列出迁移
|
||
dotnet ef migrations list `
|
||
--project .\MiGu.DB\MiGu.DB.csproj `
|
||
--startup-project .\MiGu.Server\MiGu.Server.csproj `
|
||
--context MiGuDbContext
|
||
|
||
# 生成 SQL 脚本(发版/DBA 审阅,不直接连库执行也可)
|
||
dotnet ef migrations script `
|
||
--project .\MiGu.DB\MiGu.DB.csproj `
|
||
--startup-project .\MiGu.Server\MiGu.Server.csproj `
|
||
--context MiGuDbContext `
|
||
--output .\MiGu.DB\Migrations\Sqlite\script.sql
|
||
|
||
# 从某迁移到最新(含幂等脚本时加 --idempotent)
|
||
dotnet ef migrations script FromMigration ToMigration `
|
||
--project .\MiGu.DB\MiGu.DB.csproj `
|
||
--startup-project .\MiGu.Server\MiGu.Server.csproj `
|
||
--context MiGuDbContext `
|
||
--idempotent
|
||
|
||
# 删除「尚未应用到任何重要库」的最后一次迁移(仅开发)
|
||
dotnet ef migrations remove `
|
||
--project .\MiGu.DB\MiGu.DB.csproj `
|
||
--startup-project .\MiGu.Server\MiGu.Server.csproj `
|
||
--context MiGuDbContext
|
||
|
||
# 回滚到指定迁移(会执行 Down,生产慎用)
|
||
dotnet ef database update <目标迁移名> `
|
||
--project .\MiGu.DB\MiGu.DB.csproj `
|
||
--startup-project .\MiGu.Server\MiGu.Server.csproj `
|
||
--context MiGuDbContext
|
||
```
|
||
|
||
使用本地工具时,将 `dotnet ef` 换成 `.\.tools\dotnet-ef`。
|
||
|
||
---
|
||
|
||
## 5. 启动时发生了什么
|
||
|
||
**完整说明(顺序、配置、SchemaMode、开发注意)见:**
|
||
|
||
→ **[MiGu.Server/README.md · 数据库启动流程](../MiGu.Server/README.md#数据库启动流程)**
|
||
|
||
摘要:`EnsurePlatformDatabaseAsync` → `MigrateMiGuDbAsync`;`Database:SchemaMode` 为 `EnsureCreated` 或 `Migrate`;之后按需跑 `IDataMigrator`。
|
||
|
||
**Migrate 基线:** 已有表、无 History 时,会把**全部** pending Migration 写入 `__EFMigrationsHistory`(假定 EnsureCreated 库已对齐模型 tip)。发版前若开发期改过模型,须先 `migrations add` 再切 `Migrate`。
|
||
|
||
---
|
||
|
||
## 6. Schema 变更 vs 数据修补
|
||
|
||
| 需求 | 做法 |
|
||
|------|------|
|
||
| 新表/新列/索引/改列类型 | `migrations add` → 提交迁移文件 |
|
||
| 刷旧枚举字符串、回填列 | 新增 `IDataMigrator`,注册到 `AddMiGuDataMigrators` |
|
||
| 开发机整库清空重来 | 删 `data/platform.db*` 后启动(等同空库 Migrate);**不要**在生产用 EnsureDeleted |
|
||
|
||
注意:带 `HasConversion` 的枚举列,用 `ExecuteUpdate` + 原始字符串比较可能触发转换异常;旧值刷库需绕过 converter(参见 `LegacyStatusNormalizationMigrator`)。
|
||
|
||
---
|
||
|
||
## 7. 协作与发版
|
||
|
||
1. **迁移文件必须入库**(含 Designer、Snapshot)
|
||
2. 多人同时改模型易冲突 Snapshot:保留一方迁移,另一方 `remove` 后基于最新代码重新 `add`
|
||
3. 已合并到主分支并可能已应用到共享库的迁移:**不要** `migrations remove` 或改写历史 `Up()`
|
||
4. 发版包随程序集带上 Migration;现场首次升级靠启动 Migrate(或预执行 `migrations script`)
|
||
|
||
---
|
||
|
||
## 8. 其他 Provider(预留)
|
||
|
||
`IDbProviderSetup` 已预留 MySql / Npgsql / SqlServer。首轮只有 Sqlite 迁移套。
|
||
|
||
将来为企业库生成独立套时:
|
||
|
||
```powershell
|
||
# 示例:输出到 Migrations/MySql,namespace 同步修改
|
||
dotnet ef migrations add InitialPlatform `
|
||
--project .\MiGu.DB\MiGu.DB.csproj `
|
||
--startup-project .\MiGu.Server\MiGu.Server.csproj `
|
||
--output-dir Migrations/MySql `
|
||
--namespace MiGu.DB.Migrations.MySql `
|
||
--context MiGuDbContext
|
||
```
|
||
|
||
并确保对应 Provider 的 `MigrationsAssembly` / 运行时能发现该套迁移(按需拆程序集或过滤命名空间)。
|
||
|
||
---
|
||
|
||
## 9. 常见问题
|
||
|
||
| 现象 | 处理 |
|
||
|------|------|
|
||
| `dotnet ef` 找不到 | 安装 8.0.10 工具,或用 `.\.tools\dotnet-ef` |
|
||
| Design-time 连错库 | 检查 `MiGuDbContextFactory`(默认 `platform.db`);运行时以 Server 配置为准 |
|
||
| Snapshot 生成到奇怪目录 | 移回 `Migrations/Sqlite/` |
|
||
| 旧库启动重复建表失败 | 确认基线逻辑是否写入 History;备份后必要时手工插入 Initial 行 |
|
||
| 改完实体 `add` 生成空迁移 | 模型无差异或未编译;先 `dotnet build` |
|
||
| 想撤销未提交的迁移 | `migrations remove`(确认未被他人/现场应用) |
|
||
|
||
---
|
||
|
||
## 10. 检查清单(每次提 PR)
|
||
|
||
- [ ] `dotnet build` 通过
|
||
- [ ] 新迁移仅含预期 DDL
|
||
- [ ] 文件在 `Migrations/Sqlite/`,Snapshot 路径正确
|
||
- [ ] 本地启动一次,确认 Migrate 成功
|
||
- [ ] 若有数据刷库,已加幂等 `IDataMigrator` 并注明 Order
|
||
- [ ] 未改写已发布的历史 Migration
|