This was one of these frustrating days where you're trying to get something done but it just doesn't seem to work. In this case I was trying to get a custom Entity Framework 6 migration working. There is an excellent guide by Rowan Miller that explains exactly how it's done but, well, it doesn't work… His guide is from February 2013 so maybe stuff has changed since then, I don't know. All other howtos I found have the same problem.
The TLDR version of my story is: don't create a DbMigration yourself but let Visual Studio create it for you with the Add-Migration Powershell cmdlet. When you create it yourself, the Update-Database cmdlet doesn't see your migration so it will never be executed. By simply using Add-Migration you can add an empty migration and update it as needed.
For anyone still reading this, I wanted to create a custom migration that creates a new schema in a SQL Azure database. Pretty simple stuff, it should run the statement: create schema <schema_name>. You can follow Rowan's guide except where he creates the DbMigration implementation (the class with the Up and Down methods). According to Rowan, after registering our custom SqlServerMigrationSqlGenerator it should be as simple as calling the Update-Database cmdlet and your migration is executed. However, my brand new migration didn't run: No pending explicit migrations.
System.Data.Entity.Migrations.Infrastructure.MigrationsException: The specified target migration 'CreateSecuritySchema' does not exist. Ensure that target migration refers to an existing migration id.
Your migration must be a subclass of DbMigration, makes sense.
Your migration must implement IMigrationMetadata. I had never seen or heard of this interface before. It defines three string getters: Id, Source and Target. Id makes sense, Source and Target are respectively the state of the model before/after this migration is run.
The migration class must exist in a specific namespace.
I you check migrations that are generated by the Add-Migration cmdlet, the IMigrationMetadata.Source is always null, the IMigrationMetadata.Target is a large base64-encoded string. Decoding it reveals that it is a binary file. Searching around reveals that the binary file is a compressed version of the data model EDMX file. So the Target is a snapshot of a particular state of your data model.