Это действительно агрессивный (ре) инициализатор базы данных для EF-кода с миграциями; используйте его на свой страх и риск, но, кажется, он работает довольно многократно для меня. Это будет;
- Принудительно отключить любые другие клиенты от БД
- Удалить БД.
- Перестройте БД с миграциями и запустите метод Seed
- Возьми целую вечность! (следите за пределом времени ожидания для вашей тестовой среды; 60-секундного таймаута по умолчанию может быть недостаточно)
Вот класс;
public class DropCreateAndMigrateDatabaseInitializer<TContext, TMigrationsConfiguration>: IDatabaseInitializer<TContext>
where TContext: DbContext
where TMigrationsConfiguration : System.Data.Entity.Migrations.DbMigrationsConfiguration<TContext>, new()
{
public void InitializeDatabase(TContext context)
{
if (context.Database.Exists())
{
// set the database to SINGLE_USER so it can be dropped
context.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, "ALTER DATABASE [" + context.Database.Connection.Database + "] SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
// drop the database
context.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, "USE master DROP DATABASE [" + context.Database.Connection.Database + "]");
}
var migrator = new MigrateDatabaseToLatestVersion<TContext, TMigrationsConfiguration>();
migrator.InitializeDatabase(context);
}
}
Используйте это так;
public static void ResetDb()
{
// rebuild the database
Console.WriteLine("Rebuilding the test database");
var initializer = new DropCreateAndMigrateDatabaseInitializer<MyContext, MyEfProject.Migrations.Configuration>();
Database.SetInitializer<MyContext>initializer);
using (var ctx = new MyContext())
{
ctx.Database.Initialize(force: true);
}
}
Я также использую трюк Ладислава Мрнки 'Pooling = false', но я не уверен, требуется ли он или просто мера пояса и подтяжки. Это, безусловно, будет способствовать еще большему замедлению теста.