RikMigrations: A Quick Introduction

It has been around 4 months that I have been playing with ruby and rails for personal projects and the fun and efficiency of working with it is pretty much awesome to say the least - specially since I love doing web applications and, even though I enjoy developing with C#, I totally hate doing anything web related within .NET, I really think the whole asp.net idea stinks pretty bad (not as bad as java, of course!).

Those points aside, one of the really kicking features that comes out of the box with rails is the migrations. A mean to do some actual version control with your database structure - something that I’ve experienced to be quite a pain to deal with on other various platforms.

Currently I’ve been doing mainly .NET projects at work - which is great since our main database is SQL Server and it gets along pretty well with LINQ - although it might not be as "magical" as ActiveRecord, it is pretty good and flexible. Besides, C# have become a quite modern and powerful language, with plenty of resources like lambda expressions, anonymous types, functional constructs, class extensions and so on.

We have a great and positive work environment, with CI (using hudson - which, unfortunately is made in java), git, and getting more and more TDD/BDD/DDD centered and mature with each new project that comes. One thing that we were definitely missing though, while working with .NET, is a proper database versioning tool, specially for parallel development scenarios.

Fortunately, a couple of weeks ago, one of my teammates came up with some "rails migrations" equivalents for .NET. We’ve fiddled a bit with two of the seemingly most reliable options: Migrator and RikMigrations.

They’re both open source tools, still in a quite beta stage - but quite functional already. We’ve decided to stick with RikMigrations, since the syntax seemed more appealing to us - even though the project has been kind of abandoned for some time now, while Migrator still alive and kicking.

I’ll give a very quick go on where to start with RikMigrations, here are some basic steps (I’ll assume you know your way around visual studio):

  1. Go to the project website and download it.
  2. Add the RikMigrations.exe as a reference to your project.

    image

  3. Create a class to be your migration, in my case, as you can see above, I’ve named it "_00001_CreateTableUsers.cs". The number in the beginning of the class is NOT mandatory - but since every migration will have to have a sequential version, it should help to keep things organized. This works kind of like rails migrations around rails version 2.0.
  4. Now, for the class content - it should implement the IMigration interface:
    // This defines:
    //  # The version that this migrations upgrades your database to (in this case: 1)
    //  # The type of the migration, which should be the class itself
    //  # The project name - you may wish to control the versioning of your database separated for subsets of tables
    [assembly: Migration(1, Type = typeof(_00001_CreateTableUsers), ModuleName = "Example")]
    
    namespace Com.MACSkeptic.RikMigrations.Example.Migrations
    {
        public class _00001_CreateTableUsers : IMigration
        {
            #region IMigration Members
    
            // The method executed to undo this migration
            public void Down(DbProvider db)
            {
                throw new NotImplementedException();
            }
    
            // The method executed to do this migration
            public void Up(DbProvider db)
            {
                throw new NotImplementedException();
            }
    
            #endregion
        }
    }
  5. Finally, lets implement the Down and Up methods:

     public void Down(DbProvider db)
     {
         db.DropTable("USERS");
     }
    
     // The method executed to do this migration
     public void Up(DbProvider db)
     {
         Table users = db.AddTable("USERS");
    
         //an int primary key auto-increment
         users.AddColumn("id", typeof(int)).NotNull().PrimaryKey().AutoGenerate();
    
         //a not null varchar(100) field
         users.AddColumn("name", typeof(string), 100).NotNull().NotUnicode();
    
         //a nullable nvarchar(100) field
         users.AddColumn("email", typeof(string), 100);
    
         users.Save();
     }
  6. Now to run our migrations we just need to call a method (I made it a console app, but you can just call it on the beginning of your tests):

    namespace Com.MACSkeptic.RikMigrations.Example
    {
        class Program
        {
            static void Main(string[] args)
            {
                DbProvider.DefaultConnectionString = @"Data Source=MARVINSQLEXPRESS;Initial Catalog=test;Integrated Security=True";
                //You just need to inform the Assembly from which you want to run migrations from
                MigrationManager.UpgradeMax(typeof(Program).Assembly);
            }
        }
    }
  7. Running this should create two tables:
    1. ModuleVersions

      image

    2. Users

image

 

And that’s basically it.

If you like, you can download the full sample code in ZIP, or RAR

Tags: , , , , , , ,

2 People have left comments on this post



» st.Jhimy said: { May 9, 2009 - 06:05:58 }

The “Visual Studio magick” doesn’t works preety fine with others databases like you said, but always have another way, i’ve using entity framework and getting some exciting results with other databases, of course…it´s not the same thing…anyway.

http://docs.openlinksw.com/virtuoso/vdbenginepsql.html

» MACSkeptic said: { May 9, 2009 - 08:05:28 }

That’s cool. I’ve read it somewhere that you can also use NHibernate behind the scenes to get Entity to work with other databases besides SQL Server - but haven’t tried it myself.

I’m kind of a mortal enemy to anything that needs any sort of XML configuration - I’d rather write dozens of lines of actual code than a single line of XML.