我正在使用MVC 4,Entity Framework 5和Code First方法。
当我对模型进行更改并运行应用程序时,我收到一条错误,因为它正在使用中而无法删除数据库。
为了解决这个问题,我实现了自己的IDatabaseInitializer
来强制建立一个像这样的连接:
public class ForceDropCreateDatabaseInitializer<T> : IDatabaseInitializer<T> where T : DbContext, new()
{
public ForceDropCreateDatabaseInitializer(Action<T> seed = null)
{
Seed = seed ?? delegate { };
}
public Action<T> Seed { get; set; }
public void InitializeDatabase(T context)
{
if (context.Database.Exists())
{
string databaseName = context.Database.Connection.Database;
string alterStatement = "ALTER DATABASE [{0}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE";
string dropStatement = "USE [master] DROP DATABASE [{0}]";
context.Database.ExecuteSqlCommand(alterStatement, databaseName);
context.Database.ExecuteSqlCommand(dropStatement, databaseName);
}
context.Database.Create();
Seed(context);
}
}
但是现在我在这一行收到了权限错误:
context.Database.ExecuteSqlCommand(alterStatement, databaseName);
异常消息:
用户无权更改数据库'@ p0',数据库不存在,或者数据库未处于允许访问检查的状态。
ALTER DATABASE语句失败。
我认为使用@ p0因为我正在使用参数。如何在每次进行模型更改时避免此错误并成功删除并创建数据库?
答案 0 :(得分:1)
我尝试在此处使用您的问题来修复我在使用中删除数据库的问题。不幸的是,我遇到了下面讨论的另一个问题。 Here is the code I used that might fix the issue for you by completing it slightly differently:
// Somewhere in Global.asax
Database.SetInitializer(new DbInitializer());
// DbInitializer
public class DbInitializer : IDatabaseInitializer<Context>
{
public void InitializeDatabase(Context context)
{
if (context.Database.Exists())
{
//if (!context.Database.CompatibleWithModel(true))
//{
string singleUserModeCommand =
string.Format("ALTER DATABASE [{0}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE",
"databasename" /*context.Database.Connection.Database does not seem to work here so i have "fixed" the database name rather than letting it be dynamic*/);
if (context.Database.Exists())
{
context.Database.ExecuteSqlCommand(singleUserModeCommand);
context.Database.Delete();
}
context.Database.Create();
Seed(context);
//}
}
else
{
context.Database.Create();
Seed(context);
}
}
protected void Seed(Context context)
{
}
}
使用此代码时遇到的最大问题是
context.Database.Connection.Database
似乎不想解析数据库名称并继续给我错误:
对象或列名称缺失或为空。对于SELECT INTO 声明,验证每列是否有名称。对于其他陈述,请查看 对于空别名。不允许使用定义为“”或[]的别名。 添加名称或单个空格作为别名。
所以我只修改了Context类中的数据库名称:
public class MyContext : DbContext
{
public MyContext()
base: ("databasename")
{}
}