|
|
||
|---|---|---|
| .. | ||
| readme.md | ||
readme.md
数据库迁移指南
本项目使用 Entity Framework Core 迁移。迁移文件生成在:
AML_Backend/src/iCON.Abp.FX.EntityFrameworkCore.DbMigrations/Migrations/
对应的 DbContext 为 FXMigrationsDbContext,设计时工厂为
EntityFrameworkCore/FXMigrationsDbContextFactory.cs。
生成迁移有两条等价路径:A. Visual Studio 包管理器控制台(Windows) 与
B. dotnet ef 命令行(macOS / Linux / 无 VS 的开发环境)。二者产物完全一致,
按你的操作系统任选其一即可。
说明:迁移只在开发/构建环境生成(生成
*.cs+ 更新ModelSnapshot); 运行时由Database.Migrate()自动应用到数据库。不要用手写ALTER TABLE代替生成迁移——运行时会读取迁移里的TargetModel(完整模型快照)做比对, 缺少对应迁移会导致模型不一致。手动改库仅可作为本地临时应急。
路径 A · Visual Studio 包管理器控制台(Windows)
前置条件
- Visual Studio 开发环境
- 确保解决方案已成功构建
- 已安装 EF Core 工具
步骤
- 将
EntityFrameworkCore.DbMigrations设为启动项目 - 打开包管理器控制台(Package Manager Console)
- 默认项目选择:
src\iCON.Abp.FX.EntityFrameworkCore.DbMigrations - 执行:
Add-Migration <MigrationName> - 迁移会在下次运行时自动应用
- 撤销上一个(尚未应用的)迁移:
Remove-Migration
路径 B · dotnet ef 命令行(macOS / Linux / 无 VS)
Add-Migration(PMC)与 dotnet ef migrations add(CLI)是同一功能的两种入口。
在没有 Visual Studio 的开发机(如本机 macOS)上,完全可以就地生成迁移,用 CLI 即可。
本机已按此流程实测生成过
AddAssignedAgentUserIdToFeedback(Feedback表新增 可空列AssignedAgentUserId),产物与既有 EF Core 5.0.17 迁移格式一致。
B.0 前置条件(本机现状与坑)
| 前置项 | 现状 / 处理 |
|---|---|
| dotnet-ef 工具 | 项目未自带。用本地工具清单安装(见 B.1)。 |
| .NET 运行时 | 项目 target net6.0;本机可能只装了更高版本(如 .NET 10)。构建不受影响,但运行设计时宿主需 roll-forward(见 B.2)。 |
| 设计时配置来源 | FXMigrationsDbContextFactory 从 src/iCON.Abp.FX.DbMigrator/appsettings.json + Nacos 读取 DBConfig / ConnectionStrings。开发机若连不上 Nacos(默认 192.168.1.120:8848),需改用本地优先配置离线生成(见 B.3)。 |
B.1 安装 dotnet-ef(本地工具清单,一次性)
在 AML_Backend/ 目录下:
cd AML_Backend
dotnet new tool-manifest # 若已有 .config/dotnet-tools.json 或 dotnet-tools.json 可跳过
dotnet tool install dotnet-ef # 或指定版本:--version "10.*"
dotnet ef --version # 验证
dotnet-ef工具版本可高于项目的 EF Core 版本(本机用 10.0.9 生成 EF Core 5 的迁移没问题)—— 代码生成用的是项目引用的 EF Core Design(5.0.*),所以产物仍是 5.0.17 格式,与既有迁移一致。
B.2 运行时 roll-forward(仅当本机缺少 net6.0 运行时)
dotnet ef 会构建启动项目(net6.0)并在该运行时里启动设计时宿主。本机若只有 .NET 10,
需允许从 net6 向上滚动到已装的运行时,给命令加环境变量:
DOTNET_ROLL_FORWARD=LatestMajor dotnet ef migrations add ...
(若本机已装 .NET 6 运行时,则不需要这个变量。)
B.3 离线配置:绕开不可达的 Nacos(仅当连不上 Nacos)
FXMigrationsDbContextFactory 通过 AddNacosV2ConfigurationLocalFirst() 读取配置:
本地 appsettings.json 里若没有 NacosConfig 节点,就完全不连 Nacos、只用本地配置。
利用这一点,把 src/iCON.Abp.FX.DbMigrator/appsettings.json 临时替换为本地优先版本
(去掉 NacosConfig,补上 DBConfig 与连接串)。
生成迁移(
migrations add)不会真的连库,只需连接串可解析(非空)即可; 指向本机 docker 的 SQL Server 最稳妥。
cd AML_Backend/src/iCON.Abp.FX.DbMigrator
cp appsettings.json appsettings.json.nacos-bak # 备份
cat > appsettings.json <<'JSON'
{
"DBConfig": { "DBType": "mssql", "ConnectionStringName": "Default" },
"ConnectionStrings": {
"Default": "Server=localhost,11433;Database=AbpAML;User Id=sa;Password=Aml@Local2026;TrustServerCertificate=True"
}
}
JSON
(localhost,11433 / sa / Aml@Local2026 为 docs/AML_Backend/docker-compose-local-dev 本地栈的库;
按你的本地环境替换。)
生成完成后务必还原,避免把本地连接串提交进仓库:
mv -f appsettings.json.nacos-bak appsettings.json
B.4 生成迁移
在 AML_Backend/ 目录下执行(项目与启动项目都指向 DbMigrations,
设计时工厂就在其中,../iCON.Abp.FX.DbMigrator/appsettings.json 会被正确解析到):
cd AML_Backend
DOTNET_ROLL_FORWARD=LatestMajor dotnet ef migrations add <MigrationName> \
--project src/iCON.Abp.FX.EntityFrameworkCore.DbMigrations \
--startup-project src/iCON.Abp.FX.EntityFrameworkCore.DbMigrations \
--context FXMigrationsDbContext
看到 Build succeeded. + Done. 即成功。会生成两文件并更新快照:
Migrations/<时间戳>_<MigrationName>.cs(Up/Down)Migrations/<时间戳>_<MigrationName>.Designer.csMigrations/FXMigrationsDbContextModelSnapshot.cs(追加本次模型变更)
核对:git diff --stat 看快照,确认只包含你本次改的实体属性(若夹带了别的变更,
说明工作树里还有未生成迁移的模型改动,需甄别)。
撤销刚生成、尚未应用的迁移:
DOTNET_ROLL_FORWARD=LatestMajor dotnet ef migrations remove \
--project src/iCON.Abp.FX.EntityFrameworkCore.DbMigrations \
--startup-project src/iCON.Abp.FX.EntityFrameworkCore.DbMigrations \
--context FXMigrationsDbContext
已生成示例(AssignedAgentUserId)
20260706234441_AddAssignedAgentUserIdToFeedback.cs:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<Guid>(
name: "AssignedAgentUserId",
table: "AMLPortal_Feedbacks",
type: "uniqueidentifier",
nullable: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "AssignedAgentUserId",
table: "AMLPortal_Feedbacks");
}
注意事项
- 每次修改实体模型后都要生成一个新迁移,并连同更新后的
ModelSnapshot一起提交。 - 迁移在下次运行
DbMigrator/ Host(Database.Migrate())时自动应用到数据库。 - 生成迁移不需要真连库;应用迁移才需要连接串正确、且账号有 DDL 权限。
- 别把 B.3 里临时的本地连接串(
appsettings.json)提交进仓库。