Files
TakeoutSaaS.AdminApi/Document/10_设计期DbContext配置指引.md

132 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 设计时 DbContext 配置指引
> 目的:在执行 `dotnet ef` 命令时无需硬编码数据库连接,可根据 appsettings 与环境变量自动加载。本文覆盖环境变量设置、配置目录指定等细节。
## 三库迁移命令 只需更改 SnowflakeIds_App 迁移关键字
> 先生成迁移,再执行数据库更新。启动项目统一用 AdminApi 确保加载最新配置。
### 生成迁移
```bash
# App 主库
dotnet tool run dotnet-ef migrations add SnowflakeIds_App `
--project src/Infrastructure/TakeoutSaaS.Infrastructure/TakeoutSaaS.Infrastructure.csproj `
--startup-project src/Api/TakeoutSaaS.AdminApi/TakeoutSaaS.AdminApi.csproj `
--context TakeoutSaaS.Infrastructure.App.Persistence.TakeoutAppDbContext
# Identity 库
dotnet tool run dotnet-ef migrations add SnowflakeIds_Identity `
--project src/Infrastructure/TakeoutSaaS.Infrastructure/TakeoutSaaS.Infrastructure.csproj `
--startup-project src/Api/TakeoutSaaS.AdminApi/TakeoutSaaS.AdminApi.csproj `
--context TakeoutSaaS.Infrastructure.Identity.Persistence.IdentityDbContext
# Dictionary 库
dotnet tool run dotnet-ef migrations add SnowflakeIds_Dictionary `
--project src/Infrastructure/TakeoutSaaS.Infrastructure/TakeoutSaaS.Infrastructure.csproj `
--startup-project src/Api/TakeoutSaaS.AdminApi/TakeoutSaaS.AdminApi.csproj `
--context TakeoutSaaS.Infrastructure.Dictionary.Persistence.DictionaryDbContext
```
### 更新数据库
```bash
dotnet tool run dotnet-ef database update `
--project src/Infrastructure/TakeoutSaaS.Infrastructure/TakeoutSaaS.Infrastructure.csproj `
--startup-project src/Api/TakeoutSaaS.AdminApi/TakeoutSaaS.AdminApi.csproj `
--context TakeoutSaaS.Infrastructure.App.Persistence.TakeoutAppDbContext
dotnet tool run dotnet-ef database update `
--project src/Infrastructure/TakeoutSaaS.Infrastructure/TakeoutSaaS.Infrastructure.csproj `
--startup-project src/Api/TakeoutSaaS.AdminApi/TakeoutSaaS.AdminApi.csproj `
--context TakeoutSaaS.Infrastructure.Identity.Persistence.IdentityDbContext
dotnet tool run dotnet-ef database update `
--project src/Infrastructure/TakeoutSaaS.Infrastructure/TakeoutSaaS.Infrastructure.csproj `
--startup-project src/Api/TakeoutSaaS.AdminApi/TakeoutSaaS.AdminApi.csproj `
--context TakeoutSaaS.Infrastructure.Dictionary.Persistence.DictionaryDbContext
```
## 一、设计时工厂读取逻辑概述
设计时工厂(`DesignTimeDbContextFactoryBase<T>`)按下面顺序解析连接串:
1. 若设置了 `TAKEOUTSAAS_APP_CONNECTION` / `TAKEOUTSAAS_IDENTITY_CONNECTION` / `TAKEOUTSAAS_DICTIONARY_CONNECTION` 等环境变量,则优先使用。
2. 否则查找配置文件:
- 从当前目录开始向上找到含 `TakeoutSaaS.sln` 的仓库根。
- 依次检查 `src/Api/TakeoutSaaS.AdminApi``src/Api/TakeoutSaaS.UserApi``src/Api/TakeoutSaaS.MiniApi` 等目录,如果存在 `appsettings.json``appsettings.{Environment}.json` 则加载。
- 若未找到,可通过环境变量 `TAKEOUTSAAS_APPSETTINGS_DIR` 指定包含 appsettings 文件的目录。
配置结构示例(出现在 AdminApi/MiniApi/UserApi 的 appsettings
```json
"Database": {
"DataSources": {
"AppDatabase": {
"Write": "Host=120.53...;Database=takeout_app_db;Username=...;Password=...",
"Reads": [
"Host=120.53...;Database=takeout_app_db;Username=...;Password=..."
]
},
"IdentityDatabase": {
"Write": "...",
"Reads": [ "..." ]
},
"DictionaryDatabase": {
"Write": "...",
"Reads": [ "..." ]
}
}
}
```
设计时工厂会根据数据源名称(`DatabaseConstants.AppDataSource` 等)读取 `Write` 连接串,实现与运行时一致。
## 二、环境变量配置
### 1. Windows PowerShell
```powershell
# 指向包含 appsettings.json 的目录
$env:TAKEOUTSAAS_APPSETTINGS_DIR = \"D:\\HAZCode\\TakeOut\\src\\Api\\TakeoutSaaS.AdminApi\"
#(可选)覆盖 AppDatabase 连接串
$env:TAKEOUTSAAS_APP_CONNECTION = \"Host=120.53.222.17;Port=5432;Database=takeout_app_db;Username=app_user;Password=***\"
#(可选)覆盖 IdentityDatabase 连接串
$env:TAKEOUTSAAS_IDENTITY_CONNECTION = \"Host=...;Database=takeout_identity_db;Username=...;Password=...\"
#(可选)覆盖 DictionaryDatabase 连接串
$env:TAKEOUTSAAS_DICTIONARY_CONNECTION = "Host=...;Database=takeout_dictionary_db;Username=...;Password=..."
```
### 2. Linux / macOS
```bash
export TAKEOUTSAAS_APPSETTINGS_DIR=/home/user/TakeOut/src/Api/TakeoutSaaS.AdminApi
export TAKEOUTSAAS_APP_CONNECTION=\"Host=120.53.222.17;Port=5432;Database=takeout_app_db;Username=app_user;Password=***\"
export TAKEOUTSAAS_IDENTITY_CONNECTION=\"Host=...;Database=takeout_identity_db;Username=...;Password=...\"
export TAKEOUTSAAS_DICTIONARY_CONNECTION="Host=...;Database=takeout_dictionary_db;Username=...;Password=..."
```
> 注意:若设置了 `TAKEOUTSAAS_APP_CONNECTION`,则无需在 appsettings 中提供 `Write` 连接串,反之亦然。不要将明文密码写入代码仓库,建议使用 Secret Manager 或部署环境的安全存储。
## 三、执行脚本示例
完成上述环境变量配置后即可执行:
```powershell
# TakeoutAppDbContext业务库
dotnet tool run dotnet-ef database update `
--project src/Infrastructure/TakeoutSaaS.Infrastructure/TakeoutSaaS.Infrastructure.csproj `
--startup-project src/Infrastructure/TakeoutSaaS.Infrastructure/TakeoutSaaS.Infrastructure.csproj `
--context TakeoutSaaS.Infrastructure.App.Persistence.TakeoutAppDbContext
# IdentityDbContext身份库
dotnet tool run dotnet-ef database update `
--project src/Infrastructure/TakeoutSaaS.Infrastructure/TakeoutSaaS.Infrastructure.csproj `
--startup-project src/Infrastructure/TakeoutSaaS.Infrastructure/TakeoutSaaS.Infrastructure.csproj `
--context TakeoutSaaS.Infrastructure.Identity.Persistence.IdentityDbContext
# DictionaryDbContext字典库
dotnet tool run dotnet-ef database update `
--project src/Infrastructure/TakeoutSaaS.Infrastructure/TakeoutSaaS.Infrastructure.csproj `
--startup-project src/Infrastructure/TakeoutSaaS.Infrastructure/TakeoutSaaS.Infrastructure.csproj `
--context TakeoutSaaS.Infrastructure.Dictionary.Persistence.DictionaryDbContext
```
若需迁移 Identity/Dictionary 等上下文,替换 `--context` 参数为对应类型即可。
## 四、常见问题
1. **未找到 appsettings**:确保 `TAKEOUTSAAS_APPSETTINGS_DIR` 指向存在 `appsettings.json` 的目录,或将命令在 API 项目目录中执行。
2. **密码错误**:确认远程 PostgreSQL 用户/密码是否与 appsettings 或环境变量一致,避免在 CLI 中使用默认的账号。
3. **多环境配置**`ASPNETCORE_ENVIRONMENT` 变量可控制加载 `appsettings.{Environment}.json`;默认是 Development。