Param(
[ValidateNotNullOrEmpty()][string]$assemblyFile,
[ValidateNotNullOrEmpty()][string]$connectionString
# [ValidateNotNullOrEmpty()][string]$server,
# [ValidateNotNullOrEmpty()][string]$databaseName,
# [ValidateNotNullOrEmpty()][string]$userName,
# [ValidateNotNullOrEmpty()][string]$password
)
$assemblyFolder = [System.IO.Path]::GetDirectoryName($assemblyFile)
$OnAssemblyResolve = [System.ResolveEventHandler] {
param($sender, $e)
# First load the assemblies already in our app domain
foreach($a in [System.AppDomain]::CurrentDomain.GetAssemblies())
{
if ($a.FullName -eq $e.Name)
{
return $a
}
}
$fn = Join-Path $assemblyFolder "$($e.Name.Split(',')[0]).dll"
if (Test-Path $fn)
{
$ass = [Reflection.Assembly]::LoadFile($fn)
return $ass
}
return $null
}
[System.AppDomain]::CurrentDomain.add_AssemblyResolve($OnAssemblyResolve)
Set-Location ($assemblyFolder)
[System.Reflection.Assembly] $assembly = [System.Reflection.Assembly]::LoadFile($assemblyFile)
$types = $null
try
{
$types = $assembly.GetTypes()
}
catch [Exception]
{
$ErrorMessage = $_.Exception.Message
throw "Failed to load types from assembly"
}
$configurationType = [System.Type]::GetType("System.Data.Entity.Migrations.DbMigrationsConfiguration, EntityFramework")
$migratorType = [System.Type]::GetType("System.Data.Entity.Migrations.DbMigrator, EntityFramework")
$connectionInfoType = [System.Type]::GetType("System.Data.Entity.Infrastructure.DbConnectionInfo, EntityFramework")
if ($configurationType -eq $null -or $migratorType -eq $null -or $connectionInfoType -eq $null)
{
throw "Failed to load entity framework"
}
$migrationConfigurationTypes = @($types | ? { $configurationType.IsAssignableFrom($_) })
if ($migrationConfigurationTypes.Length -ne 1)
{
throw "Failed to find single migration type for Entity framework in the assembly to migrate, found $($migrationConfigurationTypes.Length) migration configuration types"
}
Write-Warning "If you see an error similar to 'Could not find a connection string named [connection string name] in the application config', try changing your DbContext descendent to use the DbContext('connection string name') constructor syntax instead of DbContext('name=connection string name'). This is a known bug in EntityFramework."
#$builder = New-Object System.Data.SqlClient.SqlConnectionStringBuilder
# Need to use psbase, otherwise these properties throw an exception
#$builder.psbase.DataSource = $server
#$builder.psbase.InitialCatalog = $databaseName
#$builder.psbase.UserID = $userName
#$builder.psbase.Password = $password
#$connectionString = $builder.ToString()
$configuration = [System.Activator]::CreateInstance($migrationConfigurationTypes[0])
$connectionInfo = New-Object $connectionInfoType ($connectionString, "System.Data.SqlClient")
$configuration.TargetDatabase = $connectionInfo
$migrator = [System.Activator]::CreateInstance($migratorType, @($configuration))
$migrator.Update()
Write-Host 'Successfully migrated database'
Showing posts with label entity framework. Show all posts
Showing posts with label entity framework. Show all posts
Tuesday, June 21, 2016
PowerShell script to execute an Entity Framework Migration
I got sick and tired of coming up with hacks for including Entity Framework migrations as part of my deployment processes, so I came up with a much cleaner hack in the form of a PowerShell script that can be used to execute a database migration given an assembly and a connection string. This script does have one caveat though: for some reason if it's run more than once in a given PowerShell session, it causes a stack overflow exception, and I haven't been able to figure out why. I guess I'll have to leave it as an exercise to you. Have at it:
Subscribe to:
Posts (Atom)