我有一个MVC3和EF 4 Code First应用程序,该应用程序配置为在模型更改时通过将DB Initializer设置为DropCreateDatabaseIfModelChanges<TocratesDb>来更改DB,其中TocratesDb是我派生的DbContext

现在,通过向类添加属性来对模型进行更改,但是当EF尝试删除并重新创建数据库时,出现以下错误:

Cannot drop database "Tocrates" because it is currently in use.

我在此数据库上的任何地方都没有其他连接。我假设我的cDbContext仍然具有到数据库的开放连接,但是我该怎么办?

新:现在,我的问题是如何基于模型重新创建数据库。通过使用更通用的IDatabaseInitializer,我会丢失它,而必须自己实现。

最佳答案

您当前的上下文必须具有打开的连接才能删除数据库。问题在于,可能还有其他打开的连接将阻塞您的数据库初始化程序。一个很好的例子是在Management Studio中打开数据库中的任何表。另一个可能的问题是在应用程序的连接池中打开了连接。

在MS SQL中,例如,可以通过将数据库切换到“单用户”模式并强制关闭所有连接并回滚不完整的事务来避免这种情况:

ALTER DATABASE Tocrates SET SINGLE_USER WITH ROLLBACK IMMEDIATE

您可以创建一个新的初始化器,该初始化器将首先调用此命令,然后删除数据库。请注意,您应该自己处理数据库连接,因为必须在同一连接上调用ALTER DATABASEDROP DATABASE

编辑:

这里有使用装饰器模式的示例。您可以修改它并在构造函数内部初始化内部初始化程序,而不必将其作为参数传递。

public class ForceDeleteInitializer : IDatabaseInitializer<Context>
{
    private readonly IDatabaseInitializer<Context> _initializer;

    public ForceDeleteInitializer(IDatabaseInitializer<Context> innerInitializer)
    {
        _initializer = innerInitializer;
    }

    public void InitializeDatabase(Context context)
    {
        context.Database.SqlCommand("ALTER DATABASE Tocrates SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
        _initializer.InitializeDatabase(context);
    }
}

关于sql - Entity Framework 4代码优先的数据库使用中错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5288996/

10-12 12:43
查看更多