We recently switched to Entity Framework data migrations and I am working on some build automation scripts for our MVC app. I can successfully run the migrations from our build server using the migrate.exe tool in 4.3 if I have a Web.config to point it at. The command looks something like:
ProjectName\packages\EntityFramework.4.3.1\tools\migrate.exe MyAssembly
/startupdirectory:ProjectName\bin\Debug
/startupconfigurationfile:ProjectName\Web.config
/verbose
However, for various reasons I would like to avoid using the Web.config and just pass in the correct connection string at the time of the migration:
ProjectName\packages\EntityFramework.4.3.1\tools\migrate.exe MyAssembly
/startupdirectory:ProjectName\bin\Debug
/connectionString:"Data Source=awesomeserver;Initial Catalog=awesomedatabase;User Id=funkyuser;Password=crazypassword"
/verbose
This does not work. Worse, it crashes migrate.exe with a NullReferenceException. The connection string is identical to the one we use in our Web.config.
Anyone encountered this before? Is my connection string format wrong? Bug?
Ok, we figured it out. When running without the Web.config, the connectionProviderName parameter must also be passed in:
ProjectName\packages\EntityFramework.4.3.1\tools\migrate.exe MyAssembly
/startupdirectory:ProjectName\bin\Debug
/connectionProviderName:"System.Data.SqlClient"
/connectionString:"Data Source=awesomeserver;Initial Catalog=awesomedatabase;User Id=funkyuser;Password=crazypassword"
/verbose
I have confirmed that this works.
I have yet to find a solution that actually works without specifying the web/app.config file. See below.
However, if you can accept providing a web/app.config and overriding the connection string as command-line parameters, then the following works with Entity Framework 5.0 nuget and .NET 4.5. Should also work for .NET 4.0 with the documented workarounds.
Example folder structure:
trunk\MySolution.sln
trunk\run_migration.bat
trunk\MyMvc4App\MyMvc4App.csproj
trunk\MyMvc4App\web.config
trunk\MyMvc4App\bin\MyMvc4App.dll
trunk\MyMvc4App\bin\EntityFramework.dll
trunk\packages\EntityFramework.5.0.0\tools\migrate.exe
run_migration.bat:
SET AssemblyName=MyMvc4App
SET StartUpDirectory=MyMvc4App\bin\
SET ConnectionString=Server=tcp:XXXX.database.windows.net,1433;Database=XXXX;User ID=XXXX;Password=XXXX;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;MultipleActiveResultSets=True
SET ConnectionStringProvider=System.Data.SqlClient
SET ConfigFilePath=%CD%\MyMvc4App\web.config
SET MigrateExe=packages\EntityFramework.5.0.0\tools\migrate.exe
%MigrateExe% %AssemblyName%.dll /startUpDirectory:%StartUpDirectory% /startUpConfigurationFile:"%ConfigFilePath%" /connectionProviderName:"%ConnectionStringProvider%" /connectionString:"%ConnectionString%" /verbose
pause
End of solution.
Omitting the configuration file:
If trying to omit the configuration file, I always got the following exception no matter what I tried. I didn't try EF 4.3, so I suspect the behavior changed between 4.3 and 5.0.
System.Data.Entity.Migrations.Design.ToolingException: Exception has been thrown by the target of an invocation.
at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
at System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force)
at System.Data.Entity.Migrations.Console.Program.Run()
at System.Data.Entity.Migrations.Console.Program.Main(String[] args)
ERROR: Exception has been thrown by the target of an invocation.