Skip to content
dradovic edited this page Feb 16, 2011 · 29 revisions

Fluent Interface for Schema Modifications

All schema modifications can be specified in any .NET language and run on all supported database platforms. Mig# offers an intuitive fluent interface for these operations.

Multi-Module Support

Sometimes modules of an application need to co-exist in the same database and have their own versioning. Mig# migrations can be annotated with a module name to allow for this scenario.

Compatibility Validation

Migrations are checked for compatibility issues against all database platforms that should be supported. This way, problems can be detected without first having to run the migration on a specific platform.

Support for Industry Standard Relational Databases

Currently, Mig# offers support for SQL Server (2005/2008/Ce4), Oracle, and Teradata. More to come. Contributors are welcome :)

Legacy Integration

Mig# is designed to be adoptable by legacy applications that have their own versioning system in place. There are two possible levels of integration:

  1. The legacy application wants to completely replace its custom versioning mechanism. It can do so by specifying a method that tells Mig# what the current version of a given database is. Mig# then initializes its versioning table under the assumption that all previous migrations have already been executed and only executes the current pending ones.
  2. The legacy application wants to keep its versioning mechanism but wants to specify new migrations using Mig#. It can do so by implementing an interface that abstracts the versioning.

Also, the name of Mig#’s versioning table if freely configurable should there be a collision.

Non-colliding Versioning

Mig# encourages its users by convention to use non-colliding versioning “timestamps” and filenames. The timestamps are encoded in the filename as post-fixed numbers. E.g. Migration20100708113520. Adopting this convention, two teams can introduce new migrations without the need of synchronization. Merging their branches into the trunk is collision free.
If a migration with a slightly older timestamp is introduced later, Mig# executes it “a posteriori” as it keeps a list of all executed migrations.

Transactional Migrations

Each migration runs in a transaction of its own and therefore is guaranteed to succeed or fail as a whole.

Custom SQL

Migrations can also specify hand-coded SQL if needed. Example:

if (db.Context.ProviderMetadata.Name == ProviderNames.Oracle) { db.Execute("some custom SQL..."); }

Client-side Migrations

The connection and transaction objects used during the execution of a migration are exposed through a context object. They can be used if the need arises to load data to the client (who is executing the migration), transform it, and send it back to the database.

Non-intrusiveness

Migrations classes only need to implement an interface without the need of inheriting a base class.

Clone this wiki locally