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

时间:2013-02-24 11:13:12

标签: c# sql-server entity-framework testing database-connection

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

我想要实现的目标

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

出了什么问题

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

我尝试了什么

  • 数据库初始化程序
  • ALTER数据库SET SINGLE_USER WITH ROLLBACK IMMEDIATE
  • 将Pooling = false添加到连接字符串

我从thisthis 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] fixture中删除该数据库。

  
    

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

  

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

有人可以指导我吗?

1 个答案:

答案 0 :(得分:0)

此消息:

  

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

正在发生,因为您已将数据库设置为单个用户。通常,您会执行此操作以终止与数据库的其他连接,并使您的连接成为唯一可以访问它的连接。但是,如果您更改了数据库上下文,则某些其他应用程序可以连接,如Visual Studio,并成为单个用户,从而有效地锁定您。

在您的设置夹具中尝试此操作:

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

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

另一种选择是设置离线而不是single_user,但是,当您删除数据库时,它不会删除数据库.mdf&amp; .ldf(和任何.ndf)文件,因此您可能无法为另一组测试重新创建数据库。

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