168 lines
7.0 KiB
Markdown
168 lines
7.0 KiB
Markdown
# 数据库迁移指南
|
||
|
||
本项目使用 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 工具
|
||
|
||
### 步骤
|
||
1. 将 `EntityFrameworkCore.DbMigrations` 设为启动项目
|
||
2. 打开包管理器控制台(Package Manager Console)
|
||
3. 默认项目选择:`src\iCON.Abp.FX.EntityFrameworkCore.DbMigrations`
|
||
4. 执行:`Add-Migration <MigrationName>`
|
||
5. 迁移会在下次运行时自动应用
|
||
|
||
- 撤销上一个(尚未应用的)迁移:`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/` 目录下:
|
||
|
||
```bash
|
||
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 向上滚动到已装的运行时,给命令加环境变量:
|
||
|
||
```bash
|
||
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 最稳妥。
|
||
|
||
```bash
|
||
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` 本地栈的库;
|
||
按你的本地环境替换。)
|
||
|
||
**生成完成后务必还原**,避免把本地连接串提交进仓库:
|
||
|
||
```bash
|
||
mv -f appsettings.json.nacos-bak appsettings.json
|
||
```
|
||
|
||
### B.4 生成迁移
|
||
|
||
在 `AML_Backend/` 目录下执行(项目与启动项目都指向 DbMigrations,
|
||
设计时工厂就在其中,`../iCON.Abp.FX.DbMigrator/appsettings.json` 会被正确解析到):
|
||
|
||
```bash
|
||
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.cs`
|
||
- `Migrations/FXMigrationsDbContextModelSnapshot.cs`(追加本次模型变更)
|
||
|
||
**核对**:`git diff --stat` 看快照,确认只包含你本次改的实体属性(若夹带了别的变更,
|
||
说明工作树里还有未生成迁移的模型改动,需甄别)。
|
||
|
||
撤销刚生成、尚未应用的迁移:
|
||
|
||
```bash
|
||
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`:
|
||
|
||
```csharp
|
||
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`)提交进仓库。
|