我想在我的数据库中迁移存储过程和视图。由于我总是迁移到最新版本,因此源代码控制友好的方法是在迁移过程中删除/重新创建所有过程/视图(使用此方法,每个过程只有一个文件,而不是每个版本一个)。 p>
由于旧的过程/函数/视图可能与新的模式更改不兼容,我想在所有迁移之前删除,然后再进行创建。
之前我使用过定制的FluentMigrator,但现在我正在研究实体框架代码优先迁移。我发现我可以使用Seed
在所有迁移后始终运行代码。
在所有迁移之前,我可以使用什么来始终运行代码吗?
答案 0 :(得分:2)
如果您希望在迁移开始之前运行某些代码,则可以指定自定义数据库初始化程序:
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...
}
}
这会将自定义初始值设定项设置为自定义AwesomeDatabaseInitializer
,继承自MigrateDatabaseToLatestVersion
。如果您希望每次都删除并重建数据库,则应使用DropCreateDatabaseAlways
作为基类,但我不确定这可以让您运行迁移。
在初始化程序中,您可以覆盖InitializeDatabase
方法,在此方法中,您可以在调用base.InitializeDatabase
之前运行代码,这将触发数据库初始化,并依次触发Seed
方法。迁移配置,AwesomeMigrationsConfiguration
。
这是使用EF6。我不确定早期版本的实体框架中是否存在等价物。
答案 1 :(得分:2)
我有一个非常糟糕的解决方案,但适用于migrate.exe。
这是一个想法:
IDbConnectionInterceptor
以在创建MigrationsConfiguration后捕获第一个连接,然后使其取消注册。显然,绝对不是线程安全的,只有在应用程序启动或者migrate.exe中才能正常运行。示例代码:
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
}
我不确定我是否真的会使用它。