0

我正在使用 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,因为我正在使用参数。每次进行模型更改时,如何避免此错误并成功删除并创建我的数据库?

4

1 回答 1

1

我试图在这里使用您的问题来解决我删除正在使用的数据库的问题。不幸的是,我遇到了下面讨论的另一个问题。这是我使用的代码,它可能会通过稍微不同的方式为您解决问题

// 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")
    {}
}
于 2013-03-07T09:20:55.707 回答