param( [string]$Name, [ValidateSet("SQLite", "SqlServer", "PostgreSQL", "MySQL", "All")] [string]$Provider = "All", [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." } function Get-ContextName([string]$providerName) { switch ($providerName) { "SQLite" { return "SqliteAppDataContext" } "SqlServer" { return "SqlServerAppDataContext" } "PostgreSQL" { return "PostgreSqlAppDataContext" } "MySQL" { return "MySqlAppDataContext" } default { throw "Unsupported provider '$providerName'." } } } function Add-ProviderMigration([string]$providerName) { $context = Get-ContextName $providerName $providerOutputDir = Join-Path $OutputDir $providerName Write-Host "Generating migration '$Name' for $providerName..." dotnet tool run dotnet-ef migrations add $Name ` --project $Project ` --startup-project $StartupProject ` --context $context ` --output-dir $providerOutputDir if ($LASTEXITCODE -ne 0) { throw "dotnet ef migrations add failed for $providerName." } $migrationDir = Join-Path (Split-Path $Project -Parent) $providerOutputDir $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' ($providerName)." } $content = Get-Content $migrationFile.FullName -Raw $upMatch = [regex]::Match($content, "protected override void Up\(MigrationBuilder migrationBuilder\)\s*\{(?.*?)\n\s*\}", "Singleline") $downMatch = [regex]::Match($content, "protected override void Down\(MigrationBuilder migrationBuilder\)\s*\{(?.*?)\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 for $providerName. 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 for $providerName." } return } Write-Host "Migration generated for ${providerName}:" Write-Host " $($migrationFile.FullName)" } $providers = if ($Provider -eq "All") { @("SQLite", "SqlServer", "PostgreSQL", "MySQL") } else { @($Provider) } foreach ($providerName in $providers) { Add-ProviderMigration $providerName } Write-Host "Review the migration files, then start the app. Startup will apply the migration set matching DatabaseConfiguration.Provider."