Skip to content

Creating Rock Migrations

azturner edited this page Apr 15, 2013 · 10 revisions

There are some complexities with managing EF migrations in a multi-developer environment. In fact, you really have to avoid having a situation where multiple developers have created overlapping (or parallel) migrations. We've found it's best to use the following high-level strategy for adding migrations to source control:

  • Pull latest develop branch and make sure you've run the latest migrations
  • If needed, merge your develop into your feature branch.
  • Create a new migration for your branch and test, test, test (up and down).
  • If needed, merge your feature branch to the develop branch.
  • Push your develop branch to origin.

You should wait util your code is ready to commit to the develop branch before you build a migration. Once your migration is pushed it's essentially going to include it into everyone else's development environment/database. You better get it right ;)

Review and use the following checklists.

Create the new migration class

  1. Run the Dev Tools\Sql\CodeGen_PagesBlocksAttributesMigration.sql script. It will output stuff you'll want to use in your next step.
  2. Run Add-Migration [YOUR_MIGRATION_NAME]
  3. Edit this skeleton migration and paste in the stuff from the MigrationUp output into your migration's Up() method and then the MigrationDown output into the Down() method. Pay particular attention to the order that things are deleted since you cannot delete many things unless any related items are first deleted.
  4. REVIEW each item you just pasted. Not all of them will be things you should include in your migration.
  5. Manually add any other data items that were not already accounted for by the SQL script including:
  • EntityTypes
  • NoteTypes
  • PageContext (if any of your blocks use Context you should double-check this one)

Important: You should consider a few things when you're creating your Up() and Down() migration. For example, if your migration adds a new NoteType you probably won't want to delete it if there are Note records using it. Those notes are things you did not create and it would probably be bad form if you destroyed that data. Similarly, if you could not delete it during a Down() then you probably should check if it exists already during the Up(). Therefore you may want to do something like this in the Up():

    public override void Up()
    {
        Sql( @"
            -- Add 'Prayer Comment' NoteType if it's not already there
            DECLARE @PrayerCommentNoteTypeId int
            SELECT @PrayerCommentNoteTypeId = [Id] FROM [NoteType] WHERE [Guid] = '0EBABD75-0890-4756-A9EE-62626282BB5D'
            IF @PrayerCommentNoteTypeId IS NULL
            BEGIN
            INSERT INTO [NoteType] ...
                    ...
             ");
        // ...
    }

... and this in the Down():

    public override void Down()
    {
        Sql( @"
            -- Delete the NoteType but ONLY if it's not being used...
            IF NOT EXISTS(SELECT * FROM  [Note] WHERE [NoteTypeId] IN 
                (SELECT [Id] FROM [NoteType] WHERE [Guid] = '0EBABD75-0890-4756-A9EE-62626282BB5D' )
            )
            BEGIN
                DELETE [NoteType] WHERE [Guid] = '0EBABD75-0890-4756-A9EE-62626282BB5D'
            END
             ");

            // ...
    }

Test your new migration class

  1. Replace your db name with a new database name into your RockContext connection string in your web.connectionStrings.config file.
  2. Run Update-Database to see if it worked.
  3. Verify everything by running Rock (F5) and checking every detail of your stuff.
  4. If it's not good, return to step 3 in the previous section; otherwise proceed to next step.
  5. Test your Down() migration by migrating back to the last migration that exists before your new migration. Use the Update-Database TargetMigration:[THE_PREVIOUS_ONE]. If that was successful, continue.
  6. If applicable, add some data using your new blocks (if any) and re-test your Down() and your Up() migrations. This could shake out a few more assumptions you've made about your migration.
  7. When everything is looking A-OK, proceed to the Commit/Push/Deploy section; otherwise go back to step 3 in the previous section.

Commit/Push/Deploy

If everything looks good, you can commit your changes, merge into the develop branch (as needed), and push up to origin develop branch.

Clone this wiki locally