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 migration. Show all posts
Showing posts with label migration. 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:
Sunday, January 06, 2013
Wpf2WinRT: Bindings are not the same!
I've just learned something new about the bindings system in WinRT: they're not the same as Bindings in WPF. Check out the MSDN page for WinRT BindingMode, and you'll see that they're missing a value from WPF: OneWayToSource.
Migrating from WPF to Windows 8
As part of the ongoing development efforts at my company, I'm always researching the latest technologies and developments. My latest endeavour is researching Windows 8 and doing technical feasibility work to find out if it's right for us. On that front, I'm learning how to develop for the Windows 8 runtime in C#. I've got a lot of experience in WPF, and our current Line-Of-Business application is written in WPF, so I'm used to certain things, things which I'm finding no longer hold true in WinRT programming. For example, how resources such as strings are accessed in XAML. For WPF, if I wanted the internationalized string for a label, I'd do something like this :
<Label Text="{x:Static resources:Messages.UserName}"/>
However, the x:Static XAML extension no longer exists. Instead, you have to follow the *very different* ways of accessing string resources on this MSDN document, because the means of accessing resources for a WinRT application are both simpler (in some ways) and more robust, if a little bit confusing at first.
For string (and even other resources, such as images) internationalization in WinRT, what you do is this:
1. Create a folder path for your strings: \Strings\en-US
2. Under the aforementioned folder, create a resources file named Resources.resw (not that it's not .resx, as with previous .NET applications written in Windows Forms, WPF and ASP.NET)
3. Add a new string with the Name "ApplicationName.Text". The ".Text" suffix is very important; you'll see why in a minute.
4. In your XAML, create a TextBox like this:
<TextBlock x:Uid="ApplicationName" Text="" />
The Uid attribute is used for associating controls with resources, according to the MSDN link provided above, and the .Text suffix in the resource Name column, specifies the property to which the resource is linked.
Honestly, I'm not sure I like the way this is going, but if it reduces code clutter, I'm willing to at least give this a try. We'll see how this pans out.
Subscribe to:
Posts (Atom)