用户无权更改数据库

时间:2013-01-06 19:09:20

标签: sql-server-2008 asp.net-mvc-4 ef-code-first database-permissions

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

1 个答案:

答案 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")
    {}
}