As part of a continuous delivery pipeline today I wanted to automate the execution of Entity Framework Migrations from the command line. My first instinct was to see if I could add the EF PowerShell cmdlets to my PowerShell environment but it turns out these rely on the Visual Studio DTE context being available.
However it turns out that in the Entity Framework packages tools folder their is an executable that is supplied called migrate. It’s pretty simple to use but there are two caveats to running it:
- It needs to be in the same folder as the assembly that contains the migrations
- It needs to be in the same folder as the appropriate Entity Framework assembly
No big deal but on my main developer machine I still had an issue running it. Even though I copied it from the Entity Framework 6.1.2 folder, and only had that version of Entity Framework in use on my system, it complained about being run against the wrong version of Entity Framework – it appeared to be looking for version 5.0.0. This didn’t occur on a second machine but on the main developer machine I’ve had no end of problems getting Entity Framework to install the cmdlets correctly so I’m wandering if there is some cruft somewhere. In any case the fix was easy – I created a migrate.exe.config file to setup an assembly redirect as follows:
1 2 3 4 5 6 7 8 9 10 11
<?xml version="1.0" encoding="utf-8"?> <configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="EntityFramework" publicKeyToken="b77a5c561934e089" culture="neutral" /> <bindingRedirect oldVersion="0.0.0-6.1.2" newVersion="6.1.2" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
With that in place migrate ran fine. In my instance I wanted to run it using a connection string supplied by the build script and so used a command as below:
migrate MyProject.Storage.Sql.dll /connectionString="Server=(local);Database=myprojectdb;Integrated Security=True;Connection Timeout=30;" /connectionProviderName="System.Data.SqlClient"
And that’s all there is to it. Migrate will figure out if it needs to create a new database or where in the migration chain the database sits and apply migrations accordingly.
This is one of those posts that is much a reminder for myself as anything else – nevertheless I hope it’s helpful.