Reputation: 21629
I want to migrate stored procedures and views in my DB. Since I always migrate to the latest version, a source-control-friendly approach is to drop/recreate all procedures/views during migration process (with this approach there is one file per procedure, instead of one-per-version).
Since old procedures/functions/views might not be compatible with new schema changes, I want to do drop before all migrations, then do the create after all.
Previously I used a customized FluentMigrator, but now I am researching Entity Framework Code First Migrations. I see that I can use Seed
to always run code after all migrations.
Is there something I can use to always run code before all migrations?
Upvotes: 5
Views: 2759
Reputation: 21629
I have a solution that is pretty horrible, but works for migrate.exe.
Here is the idea:
IDbConnectionInterceptor
in MigrationsConfiguration constuctor to capture first connection after the MigrationsConfiguration has been created, then make it unregister itself. Obviously this is absolutely not thread-safe and only OK in application startup or migrate.exe.Example code:
public class DbMigrationsInterceptingConfiguration<TContext> : DbMigrationsConfiguration<TContext>
where TContext : DbContext
{
public DbMigrationsInterceptingConfiguration() {
BeforeFirstConnectionInterceptor.InterceptNext();
}
protected override void Seed(TContext context) {
Console.WriteLine("After All!");
}
}
internal class BeforeFirstConnectionInterceptor : IDbConnectionInterceptor {
public static void InterceptNext() {
DbInterception.Add(new BeforeFirstConnectionInterceptor());
}
public void Opened(DbConnection connection, DbConnectionInterceptionContext interceptionContext) {
// NOT thread safe
Console.WriteLine("Before All!");
DbInterception.Remove(this);
}
// ... empty implementation of other methods in IDbConnectionInterceptor
}
I am not sure I would be actually using it though.
Upvotes: 2
Reputation: 18132
If you want some code to run before migrations kick in, you can specify a custom database initializer:
public class AwesomeEntity
{
public int Id { get; set; }
}
public class AwesomeDbContext : DbContext
{
static AwesomeDbContext()
{
Database.SetInitializer(new AwesomeDatabaseInitializer());
}
public IDbSet<AwesomeEntity> Entities { get; set; }
}
public class AwesomeDatabaseInitializer : MigrateDatabaseToLatestVersion<AwesomeDbContext, AwesomeMigrationsConfiguration>
{
public override void InitializeDatabase(AwesomeDbContext context)
{
// TODO: Run code before migration here...
base.InitializeDatabase(context);
}
}
public class AwesomeMigrationsConfiguration : DbMigrationsConfiguration<AwesomeDbContext>
{
public AwesomeMigrationsConfiguration()
{
AutomaticMigrationsEnabled = true;
}
protected override void Seed(AwesomeDbContext context)
{
// TODO: Seed database here...
}
}
This sets the custom initializer to a custom AwesomeDatabaseInitializer
, which inherits from MigrateDatabaseToLatestVersion
. If you want to drop and rebuild the database every time, you should use the DropCreateDatabaseAlways
as base class instead, though I'm not sure this lets you run migrations.
In the initializer, you can override the InitializeDatabase
method, where you can run code before you call base.InitializeDatabase
, which will trigger the database initialization and in turn the Seed
method of the migration configuration, AwesomeMigrationsConfiguration
.
This is using EF6. I'm not sure if there is an equivalent in earlier versions of entity framework.
Upvotes: 2