我有一个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 DATABASE
和DROP 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/