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 に答える