I have set up continuous integration for my project with Visual Studio Online
build definitions.
When it comes to deploying my database (to an Azure test environment) I just build my SQL Server Database Project
with the right publishing settings.
But I want to switch to Entity Framework
's code first approach and leverage the migration feature, which requires me to call migrate.exe.
My question is - how could I run migrate.exe from VSO
build definitions?
I assume you are using vNext build, add a "Nuget Installer" task in your build definition first to restore the Entity Framework during the build. Migrate.exe will be installed in \packages\EntityFramework.\tools folder. Then add a "Command Line" task to run the migrate.exe. Enter “\packages\EntityFramework.\tools\migrate.exe" in "Tool" area and the arguments in "Arguments" field.
We've succesfully implemented an automated EF code first migration at deploy time on top of TFS Build vNext in the following way:
It basically involves 3 steps (per EF-context):
- Copy EF-project to a staging directory
- Copy migrate.exe in same folder (migrate.exe requires to be placed right next to assembly containing EF migrations)
- Execute migrate.exe
In detail:
- Copy Files "task"
- Source folder: $(build.sourcesdirectory)
- Contents: Contoso.EF\bin\debug\ **
- Target folder: $(build.artifactstagingdirectory)/EF
- Copy Files "task"
- Source folder: $(build.sourcesDirectory)\packages\EntityFramework.6.1.3\tools
- Contents: migrate.exe
- Target folder: $(build.artifactstagingdirectory)\EF\Contoso.EF\bin\debug\bin\debug
- Batch script "task"
- Path: $(build.sourcesdirectory)_Deploy\MigrateEFContext.bat
- Arguments: $(build.artifactstagingdirectory)\EF\Contoso.EF\bin\debug Contoso.EF.dll [SQL-SERVER-INSTANCE] [DbName] System.Data.SqlClient
The MigrateEFContext.bat file assembles the migrate.exe-command with its arguments:
SET EFDir=%1
SET EFContext=%2
SET connStringDataSource=%3
SET connStringInitialCatalog=%4
SET connectionProviderName=%5
%EFDIR%\migrate.exe %EFContext% /ConnectionString:"Data Source=%connStringDataSource%;Initial Catalog=%connStringInitialCatalog%;Integrated Security=true" /connectionProviderName:%connectionProviderName% /verbose
You can also look at executing your migrations at App startup time.
add the following to your Application_Start() event in global.asax
var configuration = new Configuration();
var migrator = new DbMigrator(configuration);
migrator.Update();
This will fire the migrations at each application startup. you could also wrap with conditional logic to control how it is fired.