132 lines
6.6 KiB
Markdown
132 lines
6.6 KiB
Markdown
# 设计时 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。
|