实体框架无法删除数据库,数据库正在使用中

本文关键字:数据库 删除 实体 框架 | 更新日期: 2023-09-27 18:00:42

我(和许多其他人一样)遇到了无法让NUnit测试删除测试夹具的[SetUp]中的数据库的问题。

我想要实现的目标

我想编写集成测试来测试我的代码,并验证预期结果是否存储在数据库中(断言CRUD方法)。也就是说,我希望能够在SqlServer中实际显示表,并查看数据库中的结果。最后一部分似乎很难实现。。。

出了什么问题

我可以连续多次运行测试。每次在[SetUp]中重新创建数据库,并且测试通过断言。只要我想在SqlServer中的实际数据库中检查我的结果,它就会耗尽。一旦我从SqlServer打开了一个连接,[SetUp]方法就不允许删除数据库,因为它有打开的连接。

我试过什么

  • 数据库初始值设定项
  • ALTER数据库SET SINGLE_USER WITH ROLLBACK IMMEDIATE
  • Pooling=false添加到连接字符串

我从这篇和这篇SO帖子中得到了这些想法。

我有什么

[SetUp]方法:

    [SetUp]
    public void SetUp()
    {
        // TenantSeedInitializer extends the 
        // DropCreateDatabaseAlways<TenantApplicationTestContext> class
        Database.SetInitializer(new TenantSeedInitializer());
        _applicationContext = new TenantApplicationTestContext();
        _applicationContext.Database.ExecuteSqlCommand("ALTER DATABASE " + 
            TenantApplicationTestContext.DatabaseName + 
            " SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
    }

[TearDown]方法:

    [TearDown]
    public void TearDown()
    {
        SqlConnection.ClearAllPools();
    }

还有一个非常直接的测试:

    [Test]
    public void AddTenant()
    {
        // add a new tenant to the database and verify that there
        // there is only one tenant present in the table  
    }

正如我所说,连续运行此测试几次非常有效,直到我尝试在SqlServer中打开表为止。

两个不同的(对我来说未解决的)错误场景

1) 或者我不被允许查看表格,因为来自visual studio的连接仍然打开

数据库"TestTenantDatabase"已打开,一次只能有一个用户。

添加SqlConnection.ClearAllPools();似乎并不能解决这个问题。

2) 或者我被允许在SqlServer中查看表,然后我不再被允许从[SetUp]设备中删除数据库

无法删除数据库"TestTenantDatabase",因为它当前正在使用中。

关闭SqlServer是我所知道的摆脱这种情况的唯一方法。但后来我发现自己在白天经常重新启动SqlServer。。。(关闭数据库连接的选项也会有所帮助,但我找不到它)。

有人能引导我度过难关吗?

实体框架无法删除数据库,数据库正在使用中

此消息:

数据库"TestTenantDatabase"已打开,并且只能有一个用户。

正在发生,因为您已将数据库设置为单用户。通常情况下,您会终止与数据库的其他连接,并使您的连接成为唯一可以访问该数据库的连接。但是,如果您更改数据库上下文,则其他应用程序(如Visual Studio)可能会连接进来,并成为单用户,从而有效地将您锁定。

在你的安装夹具中试试这个:

use TestTenantDatabase;
alter database TestTenantDatabase set single_user with rollback immediate;
use master;
drop database TestTenantDatabase;

如果您在数据库中设置单个用户,则您将成为单个用户。然后,如果您更改为master,然后在同一批中删除数据库,它应该会击败任何试图连接到它的人。

另一个选项是设置为脱机,而不是single_user,但是,当您删除数据库时,它不会删除数据库。mdf&ldf(和任何.ndf)文件,因此在为另一组测试重新创建数据库时可能会遇到问题。

如果在运行single_user时遇到与死锁相关的错误,请将死锁优先级设置为高。如果要重用连接,可以在断开后将其设置为正常。