AvaloniaStack/scripts/add-migration.ps1
luoqian c5f741e6a4 feat: 将数据库模型和迁移集中到 EFCore 项目
- 将 AppDataContext、实体模型、Migrations 从 Avalonia-Services 移动到 Avalonia-EFCore
- 更新 API、PC、Services 中的数据库上下文和实体引用命名空间
- 在实体上显式绑定表名、字段名和数据库注释
- 更新 InitialCreate、Designer、Snapshot,使用新的表名、字段名和注释
- 新增 AppDataContextFactory,支持 dotnet ef 设计时创建 DbContext
- 新增本地 dotnet-ef 工具清单
- 新增一键生成迁移脚本 add-migration.ps1 / .cmd / .bat
- 启动时自动检测并执行未应用迁移
- 从 appsettings.json 读取数据库配置
2026-05-15 15:26:46 +08:00

66 lines
2.3 KiB
PowerShell

param(
[string]$Name,
[string]$Context = "AppDataContext",
[string]$Project = "Avalonia-EFCore/Avalonia-EFCore.csproj",
[string]$StartupProject = "Avalonia-API/Avalonia-API.csproj",
[string]$OutputDir = "Migrations"
)
$ErrorActionPreference = "Stop"
$repoRoot = Resolve-Path (Join-Path $PSScriptRoot "..")
Set-Location $repoRoot
if ([string]::IsNullOrWhiteSpace($Name)) {
$Name = "AutoMigration_{0}" -f (Get-Date -Format "yyyyMMddHHmmss")
}
Write-Host "Restoring local dotnet tools..."
dotnet tool restore
if ($LASTEXITCODE -ne 0) {
throw "dotnet tool restore failed."
}
Write-Host "Generating migration '$Name'..."
dotnet tool run dotnet-ef migrations add $Name `
--project $Project `
--startup-project $StartupProject `
--context $Context `
--output-dir $OutputDir
if ($LASTEXITCODE -ne 0) {
throw "dotnet ef migrations add failed."
}
$migrationDir = Join-Path (Split-Path $Project -Parent) $OutputDir
$migrationFile = Get-ChildItem $migrationDir -Filter "*_$Name.cs" |
Where-Object { $_.Name -notlike "*.Designer.cs" } |
Sort-Object LastWriteTime -Descending |
Select-Object -First 1
if ($null -eq $migrationFile) {
throw "Migration file was not found for '$Name'."
}
$content = Get-Content $migrationFile.FullName -Raw
$upMatch = [regex]::Match($content, "protected override void Up\(MigrationBuilder migrationBuilder\)\s*\{(?<body>.*?)\n\s*\}", "Singleline")
$downMatch = [regex]::Match($content, "protected override void Down\(MigrationBuilder migrationBuilder\)\s*\{(?<body>.*?)\n\s*\}", "Singleline")
$upBody = if ($upMatch.Success) { $upMatch.Groups["body"].Value.Trim() } else { "" }
$downBody = if ($downMatch.Success) { $downMatch.Groups["body"].Value.Trim() } else { "" }
if ([string]::IsNullOrWhiteSpace($upBody) -and [string]::IsNullOrWhiteSpace($downBody)) {
Write-Host "No model changes were detected. Removing empty migration '$Name'..."
dotnet tool run dotnet-ef migrations remove --force `
--project $Project `
--startup-project $StartupProject `
--context $Context
if ($LASTEXITCODE -ne 0) {
throw "dotnet ef migrations remove failed."
}
exit 0
}
Write-Host "Migration generated:"
Write-Host " $($migrationFile.FullName)"
Write-Host "Review the migration, then start the app. Startup will automatically apply pending migrations."