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

6.6 KiB
Raw Blame History

设计时 DbContext 配置指引

目的:在执行 dotnet ef 命令时无需硬编码数据库连接,可根据 appsettings 与环境变量自动加载。本文覆盖环境变量设置、配置目录指定等细节。

三库迁移命令 只需更改 SnowflakeIds_App 迁移关键字

先生成迁移,再执行数据库更新。启动项目统一用 AdminApi 确保加载最新配置。

生成迁移

# 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

更新数据库

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.AdminApisrc/Api/TakeoutSaaS.UserApisrc/Api/TakeoutSaaS.MiniApi 等目录,如果存在 appsettings.jsonappsettings.{Environment}.json 则加载。
    • 若未找到,可通过环境变量 TAKEOUTSAAS_APPSETTINGS_DIR 指定包含 appsettings 文件的目录。

配置结构示例(出现在 AdminApi/MiniApi/UserApi 的 appsettings

"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

# 指向包含 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

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 或部署环境的安全存储。

三、执行脚本示例

完成上述环境变量配置后即可执行:

# 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。