Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Entity Framework's EF Migrations Add-Migration step require a database connection string?

I am trying to use and understand EF Migrations (using EF 4.3.1, Code First). In order to scaffold a new change, I have to use a command like this:

Add-Migration MyMigration
   -ConnectionString "Data Source=.;Initial Catalog=mydb;" 
   -ConnectionProviderName "System.Data.SqlClient"
   -StartUpProjectName MyWebsite 
   -ProjectName MyEF.Migrations

Why does Add-Migration require connection string data? Update-Database needs one, that makes sense. But doesn't Add-Migration have everything it needs from the DbContext and the Configuration?

It's not simply idle wonder, it's very confusing to give it a database, because we have a "multi-tenancy" thing where the desired database is flexible and may change from request to request, let alone at static compile time. So if Add-Migration is actually USING that database for anything, we have a problem.

UPDATE: We gave up on EF Migrations and are using Fluent Migrator instead, and are happy. It's much, much faster, even counting the fact that we have to write some things twice (once for the EF object and once for the Migration), and it doesn't have the problems discussed in this question.

like image 664
Scott Stafford Avatar asked Sep 08 '25 15:09

Scott Stafford


2 Answers

Add-Migration checks existence of the database and interacts with __MigrationHistory table. As @Anders Abel mentioned it is used for investigating pending migrations and also for selecting previous model to actually find what has changed - this is especially important if you add explicit migration into solution where automatic migrations are enabled.

like image 192
Ladislav Mrnka Avatar answered Sep 10 '25 06:09

Ladislav Mrnka


I got curious when reading your question, so I fired up a Sql Server Profiler to have a look at what's happening when add-migration is run. It does indeed connect to the database and accesses the DB to check the __MigrationHistory table.

This is also shown by the error message produced when trying to create a second code-based migration without running the first:

Unable to generate an explicit migration because the following explicit migrations are pending: [201205291928386_foo]. Apply the pending explicit migrations before attempting to generate a new explicit migration.

I think that the migrations engine uses the serialized model from the database to calculate what migration steps should be included in the new migration.

As far as I understand, the database is only used as a helper for the code generation. As long as all the various databases you use are compatible with the model in the code this shouldn't be a problem for your.

Edit

As @Ladislav Mrnka points out, a check with the database is required if mixing code-based and automatic migrations. When you scaffold up a new migration, it should include anything that has changed in your model since the last migration. If you're using automatic migrations, those are not tracked in the code. When calculating what changes to include in the migration, the last run migration is used as a base. The only way to check for that is the database - since automatic migrations might be turned on.

If you're running with only code-based migrations (which I think is the only option to keep control), then that database can be regarded as just a code generation help. As long as the model compatibility is ensured in all databases that you connect to, everything should work.

like image 33
Anders Abel Avatar answered Sep 10 '25 07:09

Anders Abel