What we finished:
On the build side, we create an idempotent script database creation:
dotnet ef migrations script --idempotent --output migrations.sql --context ApplicationContext
Where ApplicationContext is the name of your EF context and migrations.sql is the name of the sql script file.
Then, on the deployment side, we have a small powershell script that effectively runs the migrations.sql script
param( [Parameter(Mandatory)] [string]$server, [Parameter(Mandatory)] [string]$dbname, [Parameter(Mandatory)] [string]$dbadmin, [Parameter(Mandatory)] [string]$dbpassword, [Parameter(Mandatory)] [string]$migrationPath ) function Deploy-Migrations ($migrationPath,$DBSettings) { #Setting up database connection $connection = New-Object System.Data.SqlClient.SqlConnection $connection.ConnectionString = [string]::Format("Data Source=tcp:{0}.database.windows.net,1433;Initial Catalog={1};User Id={2}@{0};Password={3};MultipleActiveResultSets=True", $DBsettings['sqlServerName'], $DBsettings['databasename'],$DBsettings['adminAccount'], $DBsettings['adminPassword']) try { $connection.Open(); $SqlCmd = New-Object System.Data.SqlClient.SqlCommand $SqlCmd.Connection = $connection $query = Get-Content $migrationPath $sqlCmd.CommandText = $query.Replace("GO","") # This is required to prevent "syntax" complaints $sqlCmd.ExecuteNonQuery() Write-Host "Migration Deployed" } Catch { Write-Error "oops ... PAnic ... $($_.Exception.Message) on $($_.Exception.ItemName)" break } Finally { $connection.Close() } } $DBSettings = @{"sqlServerName"=$server; "databasename"=$dbname; "adminAccount"=$dbadmin; "adminPassword"=$dbpassword } Deploy-Migrations $migrationPath $DBSettings
ManyRootsofAllEvil
source share