- 移除 LegacyStatusNormalizationMigrator,仅保留 AreaLayoutModeDefaultMigrator - 删除 WmsDispatchStatus 枚举、常量和全局 using - 统一所有 DbContext 注入为 MiGuDbContext,移除 PlatformDbContext - 服务实体操作统一用 IEditableRepository<T>,移除本地实现 - 移除 WmsService 的 MigrateLegacyAsync 方法 - 精简接口模型,移除部分字段和请求体 - 前端保存容器时 status 字段取自已有数据,移除写死默认值 - 更新文档,去除旧说明,统一数据库初始化流程
7.6 KiB
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)执行:
# 全局工具(任选)
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,保存后编译通过:
dotnet build .\MiGu.DB\MiGu.DB.csproj
3.2 添加迁移
在解决方案根目录执行(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 生成后检查(必做)
- 新文件应在:
MiGu.DB/Migrations/Sqlite/ - 打开
*_Name.cs,确认Up()只包含本次预期变更(无误删表、无多余重建) - 确认
MiGuDbContextModelSnapshot.cs仍在Migrations/Sqlite/- 若出现在
MiGu.DB/MiGu/DB/Migrations/Sqlite/等错误路径:把 Snapshot 移回正确目录并删掉空目录(--namespace偶发路径问题)
- 若出现在
3.4 应用到本地库
启动 MiGu.Server 即可(Program.cs 直接调用 MigrateMiGuDbAsync),或:
dotnet ef database update `
--project .\MiGu.DB\MiGu.DB.csproj `
--startup-project .\MiGu.Server\MiGu.Server.csproj `
--context MiGuDbContext
4. 常用命令
# 列出迁移
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 · 数据库启动流程
摘要: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 + 原始字符串比较可能触发转换异常;空 LayoutMode 等特例用 raw UPDATE(参见 AreaLayoutModeDefaultMigrator)。
7. 协作与发版
- 迁移文件必须入库(含 Designer、Snapshot)
- 多人同时改模型易冲突 Snapshot:保留一方迁移,另一方
remove后基于最新代码重新add - 已合并到主分支并可能已应用到共享库的迁移:不要
migrations remove或改写历史Up() - 发版包随程序集带上 Migration;现场首次升级靠启动 Migrate(或预执行
migrations script)
8. 其他 Provider(预留)
IDbProviderSetup 已预留 MySql / Npgsql / SqlServer。首轮只有 Sqlite 迁移套。
将来为企业库生成独立套时:
# 示例:输出到 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