EntityFramework code based migrations, how is order determined? - entity-framework

I'm using EF 5.0 and I would like to start using Code-based migrations
I've used fluent migrator and there is a concept of migration order. Migrations can be migrated/rollback no matter the database's migration version.
Does Entity Framework have similar functionality?
I was planning on keeping multiple migration implementations for each database version (likely tied to sprint number at first).
Why do i want this?
Our continuous integration will migrate the database for each environment. It's likely that our Dev build will only be one version "behind" but when we go to QA or PROD environment the database will be behind by multiple migrations.
Maybe i'm going about this the wrong way, in which case I would love to hear opinions on the best way to do migration with CI.

Yes EF has this functionality.
When you run Add-Migration you'll notice the migration file is prefixed with a timestamp. This is what determines the order, assuming automatic migrations are and always have been disabled.
If you are using a mixture of explicit migrations and automatic migrations then you may notice an additional Source property in the .resx file generated with your migration. This is how EF will determine if it needs to run an automatic migration before it runs your explicit migration.
My experience has taught me these guidelines:
1) Never use automatic migrations.
2) Every developer on your team should ensure they have the latest code before creating a new explicit migration. Sort of obvious, but creating migrations from stale code will result in problems.
3) Developers should make sure that if they write custom SQL in the Up() method of the migration then they write appropriate code (and test it!) to reverse those changes in the Down() method.

Related

Mixing automatic and explicit migrations on the production environment

I've seen this question, and I'm wondering how automatic migrations mixed with explicit migrations would be applied on the production environment.
Let us say I create migrations in the following order:
Explicit Migration A
Explicit Migration B
Automatic Migration C
Explicit Migration D
Since no file is created for the automatic migration, how can we be sure that the automatic migration SQL that will be created on the production environment will be the same as the one created on our development machine ?
I have a sense that as soon as we have a first release on production, we should purely stop using automatic migration...
I've experimented with such scenarios before and given your migrations order this is how EF is going to behave:
When you have all those applied to database and you execute Update-Database -TargetMigration:0, then all of them will be reverted in the same order as applied.
When after execute Update-Database, all explicit migrations will be applied to the database, and given you have set AutomaticMigrationsEnabled = true; the [Timestamp]_[YourLastMigrationName]_AutomaticMigration be applied.
Beware of the fact, that EF handles the order of execution of automatic migrations! I thought that issues would occur, when I created a new table XY in the automatic migration and the following Explicit Migration D could rely on that table to be in database (and many other scenarios). But since the migrations have the snapshots of database in them, EF will be able to recover from this situation and somehow rearrange the automatic migrations.
To conclude: Without digging into entity-framework's code, I don't recommend such approach - wouldn't try my luck. In my projects I only use explicit migrations, that are maintained in one specific - usually master or iteration branch only (because of the issues when one team member has created migration B on top of A and another has created C on top of A).

Migrating from EF5 to EF6 with existing migrations

Context:
I currently have a system built on Entity Framework 5, which we'd like to upgrade to 6.
However, it already has dozens of migrations applied. And not just that, we have unit tests that verify all migrations by creating a test database and updating to latest and back to initial, to ensure all Up and Down migrations can be properly applied.
From what I've been reading, if migrations have different EF version numbers, Update-database fails to cross that boundary, meaning, the unit test covering all migrations would never pass. I could be mistaken and EF migrations might be backwards-compatible.
Question:
In that scenario, would it be wiser to actually merge all old migrations into one large InitialCreate migration (recreated using EF6), deleting the MigrationHistory table and "fake-apply" the migration to the live database (by commenting out the code of that migration temporarily) to get the new history entry?
And second of all, is this something we'll have to do again when updating EF in the near future? If that's the case then it might seem like EF is missing some support regarding cross-version migrations.
I ultimately ended up implementing what I described above in the question itself. All this was done AFTER migrating everything to EF6.
In my case I not only needed to apply this to my local database but to a live database as well.
The steps I used to accomplish that where the following (hopefully I'm not forgetting any, since this was a while back):
Backup your databases (both local and live), just in case you need to undo this.
First we need to create one merged migration for the entire database.
Change your ConnectionString to point to a new blank database.
Physically delete all migrations from your solution, as well as your initial creation one.
Run Add-Migration InitialCreate, which should add a migration to regenerate the entire database.
Now you don't really want to run that migration. In my case I only need that for unit tests, or to create new databases from scratch.
So then we continue:
Change your ConnectionString back to your local database.
Physically delete the MigrationHistory table in the database (or possibly just remove the rows, I can't recall exactly).
Comment out ALL the code whithin the InitialCreate migration, to make sure it will do nothing when applied.
Run Update-Database, which should add an entry to the MigrationHistory table simulating an initial creation of the database.
Uncomment the code in the InitialCreate migration.
The same process can be applied for the Live database. You can point to it in the ConnString, manually remove migration history, comment the implementation of the migration and apply it, to simulate creation, then uncomment.
From then on, the database and migrations should be in sync, and unit tests (on a separate database) should be able to call Down() and Up() on all migrations and still function properly.
I had also done same thing today (5-May-2014) and did not face issue mentioned by you
and had used steps suggested in
http://msdn.microsoft.com/en-us/library/upgradeef6.aspx
so my old migrations still remains the same.
Though i faced some other issues related to
- Miniprofiler (need to use new with EF6 support)
- and one issue related to re-creation of all index after upgrading.

Automatic migrations or code based migrations ? Which is better choice?

I am trying to decide code first migration strategies but not sure that which is better one.
I actualy liked automatic migrations but not sure that it can create more headache.
I have read this article and he is advocating code-based migrations. But i will not need to switch to different state in migrations so i will always use latest one and i am working in the project as single developer.
Suggestions ?
Automatic migrations were initially also referred as "with-magic migrations" whereas code-based migrations were referred as "no-magic migrations". These two names reflect exactly what is going on. Automatic migrations are implicit - you simply don't care and let them run as they need to. Code-based migrations are explicit - you define migrations in predefined steps and EF guides you in this (for example by not allowing more than one pending migration).
If you just want to have your database always up to date and you don't expect to support multiple versions or downgrades you should be OK with automatic migrations.

EF Migration - One database, two projects

We are using EF Code First with manual migration (AutomaticMigrationsEnabled = false;). The problem is that we need to share one database between two projects.
Project-A
---DbContext-A
---------Model1
---------Model2
---------Model3
Project-B
---DbContext-A
---------Model2
---------Model3
---------Model4
Some of the migration files are the same but some of them are different. For example: Project-B needs Model4 but Project-A doesn't..
Currently, If I update the database with one migration, DbContext will not work in other project.
What would be the best way to handle this scenario?
My feeling is that this is working against the intentions with migrations. I think that you should break out the DbContext, the entities and the migrations to a separate assembly that is shared between the two projects.
If that's not an option, you have to disable the compatibility check with the model. The compatibility check is done as part of the IDBInitializer.InitializeDatabase implementation, which is responsible for calling Database.CompatibleWithModel, so writing your own custom DB Initializer that does nothing would get you past that step. This also means that you take over the responsibility of ensuring that the database is compatible with the model. EF can't help you any more.

Entity Framework migrations stopped detecting the POCO updates

I'm using Entity Framework and Entity Framework migrations to implement solution using code-first and automatic migrations.
It used to work great but suddenly it stopped detecting the updates I make to my POCO. Now when I add a new property (very simple properties like age or email) and execute the Update-Database, nothing happens, and it gives me this:
Specify the '-Verbose' flag to view SQL commands being executed during migration.
Found 0 pending explicit migrations: [].
Adding seed data (if Seed method overridden in Migrations Settings class).
and nothing gets updated!
Has anyone any idea why this is happening?
This may be in two reasons:
There is some other DbContext in code, that's why automatic migrations could not decide, which context to use.
There is some new change, which loops a comparison of schema and code model, so EF simply could not find the difference.
In general, automatic migrations are simple and fast to implement, but it is not secured to use them. On some stage, such migrations could make a fail.
Several years ago, I have developed tiny ORM based on Linq2SQL, AcroDB Library, and it was using automigrations of SubSonic. Almost same as EF migrations can do now. It was perfect on small projects and small amount of data to process or change, but when project has grow into 15+ tables, it became a nightmare. That's why MS has announced Code-driven migrations lately. They are more secured and better for the project. Also, you can take a look to Migrator.Net (it is a bit better than EF, by this time).