NHibernate Migrations Proposal -- Part 1 Configuration

Welcome to the first in a series of blog posts on my proposed migrations framework for NHibernate.  This series will be updated once the feature is finalized.

The fork of NHibernate is in my github repo along with a demo of how to use the migrations

The Short Version

Implement migrations by inheriting from FluentMigration as such

	public class InitialMigration : FluentMigration
	{
		public InitialMigration() 
			: base("2014-09-23_152150_InitialMigration", "NHMigrationExample"){}

		protected override void BuildOperations(IDdlOperationBuilderSurface builder)
		{
			builder.Create.Table("`NHibernateMigrationHistory`", c => new
			{
				Context = c.String(255, nullable:false),
				Version = c.String(255, nullable: false),
				Configuration = c.BinaryBlob(2147483647)
			}).PrimaryKey(c => new{ c.Context, c.Version});

			builder.Create.Table("`Cat`", c => new
			{
				Id = c.Int32(nullable: false),
				Name = c.String(255)
			}).PrimaryKey(x => x.Id, isIdentity: true);
		}

		protected override Configuration GetConfiguration()
		{
			return new Configuration();
		}
	}

	public class AddedDog : FluentMigration
	{
		public AddedDog()
			: base("2014-09-23_154250_AddedDog", "NHMigrationExample"){}

		protected override void BuildOperations(IDdlOperationBuilderSurface builder)
		{

			builder.Alter.Table("`Cat`").AddColumn("Color", c => c.String(255));

			builder.Create.Table("`Dog`", c => new
			{
				Id = c.Int32(nullable: false),
				Name = c.String(255)
			}).PrimaryKey(x => x.Id, isIdentity: true);

		}

		protected override Configuration GetConfiguration()
		{
			return new Configuration();
		}
	}

When you set up your configuration call:

    cfg.UseTableBasedMigrations(Context: "NHMigrationExample");
cfg.RegisterAllMigrationsFrom(Assembly: typeof(MyAppConfiguration).Assembly);

then during application start-up call ISessionFactory.MigrateToLatestVersion()

    var sessionFactory = cfg.BuildSessionFactory();
    sessionFactory.MigrateToLatestVersion();

2 Comments

  • Hi, Jeff!
    So you ended up implementing a fluent interface! Nice! ;-)
    How do you apply (run) your migrations? And can you use an existing configuration? Maybe taking a constructor on the base class that receives it and a base GetConfiguration method that returns it...
    Anyway, it's good to see that you started posting your work! Keep on!
    Cheers,
    RP

  • Ricardo,
    The most straight-forward way of running the migrations is by calling the ISessionFactory.MigrateToLatestVersion() extension method. Alternatively, you could instantiate a Migrator instance and use its methods to migrate to a specific version or script out a migration.

    As for the Configuration instance, its there exclusively to support migration generation and unused at this point. If you take a look at the FluentMigration class you'll see some helper methods to deserialize a Configuration. The migration generator will compare two Configuration instances, Source and Target, generating a set of IDdlOperations off them. Target will then get serialized and burnt into the stub migration which gets generated.

Comments have been disabled for this content.