“无法删除数据库,因为它目前正在使用”。 怎么修?
有了这个简单的代码,我得到了“不能删除数据库”test_db“,因为它正在使用”(CleanUp方法),因为我运行它。
[TestFixture] public class ClientRepositoryTest { private const string CONNECTION_STRING = "Data Source=.;Initial Catalog=test_db;Trusted_Connection=True"; private DataContext _dataCntx; [SetUp] public void Init() { Database.SetInitializer(new DropCreateDatabaseAlways<DataContext>()); _dataCntx = new DataContext(CONNECTION_STRING); _dataCntx.Database.Initialize(true); } [TearDown] public void CleanUp() { _dataCntx.Dispose(); Database.Delete(CONNECTION_STRING); } }
DataContext有一个像这样的属性
public DbSet<Client> Clients { get; set; }
如何强制我的代码删除数据库? 谢谢
问题是你的应用程序可能仍然保持一些连接到数据库(或另一个应用程序持有连接)。 有其他打开的连接的地方,数据库不能被删除。 第一个问题可以通过closures连接池(将Pooling=false
添加到连接string)或删除数据库之前清除池(通过调用SqlConnection.ClearAllPools()
)来解决。
这两个问题都可以通过强制删除数据库来解决,但是您需要自定义数据库初始值设定项,将数据库切换到单用户模式,之后将其删除。 下面是一些如何实现这个function的例子。
我正在为此疯狂! 我在SQL Server Management Studio (SSMS)
内部有一个打开的数据库连接,并打开一个表查询以查看某些unit testing的结果。 当在Visual Studio中重新运行testing时,我希望它始终drop
数据库, 即使连接在SSMS中打开。
这是摆脱Cannot drop database because it is currently in use
的明确方法, Cannot drop database because it is currently in use
:
entity framework数据库初始化
诀窍是重写自定义Initializer
InitializeDatabase
方法。
复制相关部分在这里为了good
DUPLICATION … 🙂
如果数据库已经存在,您可能会遇到有错误的情况。 可以引发exception“无法删除数据库,因为它当前正在使用”。 当活动连接保持连接到正在被删除的数据库时,会发生此问题。 诀窍是重写InitializeDatabase方法并更改数据库。 这告诉数据库closures所有的连接,并且如果一个事务是打开的,回滚这个。
public class CustomInitializer<T> : DropCreateDatabaseAlways<YourContext> { public override void InitializeDatabase(YourContext context) { context.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction , string.Format("ALTER DATABASE [{0}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE", context.Database.Connection.Database)); base.InitializeDatabase(context); } protected override void Seed(YourContext context) { // Seed code goes here... base.Seed(context); } }
对于EF代码,这是一个非常积极的数据库(重新)初始化程序,首先进行迁移; 使用它在你的危险,但它似乎运行相当可重复的我。 它会;
- 从数据库强制断开任何其他客户端
- 删除数据库。
- 用迁移重build数据库并运行Seed方法
- 花时间! (注意testing框架的超时限制;默认的60秒超时可能不够)
这是class级。
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); } }
我也使用Ladislav Mrnka的“Pooling = false”技巧,但我不确定是需要还是只是一个腰带和大括号的措施。 这肯定会有助于减缓testing。
没有任何解决scheme为我工作。 我结束了写作扩展方法:
private static void KillConnectionsToTheDatabase(this Database database) { var databaseName = database.Connection.Database; const string sqlFormat = @" USE master; DECLARE @databaseName VARCHAR(50); SET @databaseName = '{0}'; declare @kill varchar(8000) = ''; select @kill=@kill+'kill '+convert(varchar(5),spid)+';' from master..sysprocesses where dbid=db_id(@databaseName); exec (@kill);"; var sql = string.Format(sqlFormat, databaseName); using (var command = database.Connection.CreateCommand()) { command.CommandText = sql; command.CommandType = CommandType.Text; command.Connection.Open(); command.ExecuteNonQuery(); command.Connection.Close(); } }
我尝试添加像Ladislav Mrnka说的Pooling=false
但总是得到错误。
我正在使用Sql服务器pipe理工作室 ,即使我closures所有的连接,我得到的错误。
如果我closuresSql Server Management Studio,那么数据库被删除:)
希望这可以帮助
我得到了同样的错误。 就我而言,我只是closures了与数据库的连接,然后重新连接,一旦在我的情况下,新的模型被添加,并且一个新的控制器被脚手架。 然而,这是一个非常简单的解决scheme,如果你想保留你的数据,不build议用于所有场景。
那时我也遇到了同样的问题。 原来,解决方法是closuresVisual Studio中服务器资源pipe理器选项卡中的连接。 所以也许你可以检查连接是否仍然在服务器资源pipe理器中打开。