17

時々、開発データベースを削除して、EFコードファーストアプリケーションを実行します。エラーが発生します:

ログインで要求されたデータベース「AssessmentSystem」を開くことができません。ログインに失敗しました。ユーザー「AssessmentAdmin」のログインに失敗しました。

これは、このページDbContextにあるように、「コンテキストが初めて使用されるときにAppDomainごとに1回」DB初期化ロジックを実行するだけだからだと思います。これは、データベースを削除した場合にEFがデータベースを再作成できるように、IISアプリケーションプールをリサイクルする必要があることを意味します。

データベースにアクセスしようとするたびにDB初期化コードを実行する方法はありますか?したがって、DBが存在するかどうかを常に確認し、存在しない場合は、以前に削除したデータベースにアクセスしたのと同じAppDomainを使用している場合でも、DBを開こうとするのではなく作成しますか?

この初期化チェックをすべてのクエリで実行したいので、それを実行してApplication_Startも十分ではない場合が多いことに注意してください。理想的には、いくつかのDBデータをロードし、DBを削除してから、いくつかのDBデータをロードできるようにしたいと思います。そうすれば、アプリケーションを再起動しなくてもDBが再作成されます(基本的には、Webページをリロードするだけです。一部のDBデータをロードします)。

4

1 に答える 1

37

イニシャライザは、データベースにアクセスする必要があるときに実行されるため、アプリの起動時にデータベースを作成する場合は、次のいずれかを使用します。

    context.Database.Initialize(true); //If set to true the initializer is run even if it has already been run.       
    context.Database.Create()

http://msdn.microsoft.com/en-us/library/system.data.entity.database.initialize(v=vs.103).aspx

CreateDatabaseIfNotExists データベースが存在しない場合にのみ、データベースを再作成し、必要に応じてデータを再シードする IDatabaseInitializer の実装。データベースをシードするには、派生クラスを作成して Seed メソッドをオーバーライドします。

Database.SetInitializer<MyContext>(new CreateDatabaseIfNotExists<MyContext>());

http://msdn.microsoft.com/en-us/library/gg679221(v=vs.103).aspx

DropCreateDatabaseIfModelChanges IDatabaseInitializer の実装で、データベースの作成後にモデルが変更された場合にのみ、データベースを削除、再作成、および必要に応じてデータを再シードします。これは、店舗モデルのハッシュを作成時にデータベースに書き込み、そのハッシュを現在のモデルから生成されたハッシュと比較することによって実現されます。データベースをシードするには、派生クラスを作成して Seed メソッドをオーバーライドします。

初期化戦略では、オプションでデータベースの存在を確認し、新しいデータベースを作成し、データベースにデータをシードできます。デフォルトの戦略は、CreateDatabaseIfNotExists のインスタンスです。

Database.SetInitializer(新しい DropCreateDatabaseIfModelChanges());

これは、データベースを削除する権限があることを前提としていることに注意してください。

http://msdn.microsoft.com/en-us/library/gg679604(v=vs.103).aspx

DropCreateDatabaseAlways

アプリケーション ドメインでコンテキストが初めて使用されるときに、常にデータベースを再作成し、必要に応じてデータを再シードする IDatabaseInitializer の実装。データベースをシードするには、派生クラスを作成して Seed メソッドをオーバーライドします。

Database.SetInitializer<MyContext>(new DropCreateDatabaseAlways<MyContext>());

http://msdn.microsoft.com/en-us/library/gg679506(v=vs.103).aspx

追跡する場合は、移行を確認し、DB に加えた変更を以前の状態http://msdn.microsoft.com/hr-hr/data/jj591621に戻すことをお勧めします。

アップデート

context.Database.Initialize(true);

パラメータ force が true に設定されている場合、以前に実行されたかどうかに関係なく、イニシャライザが実行されます。これは、アプリの実行中にデータベースが削除され、再初期化が必要な場合に役立ちます。

MVC アプリケーションの場合、 Global.asaxApplication_Start()のメソッドにセクションを追加します。

protected void Application_Start() {

     Database.SetInitializer<MyContext>(new DropCreateDatabaseAlways<MyContext>()); 

     // Forces initialization of database on model changes.
     using (var context= new MyContext()) {
          context.Database.Initialize(force: true);
     }    
}

また、カスタム初期化子を使用することもできます:

public class MyDbInit : DropCreateDatabaseAlways<MyContext>
{

}

そして使用する

Database.SetInitializer(new MyDbInit());

更新 2

DeleteDBOnEveryRequestという新しい空の MVC4 アプリケーションを作成します。以下を Global.asax Application_start に入れます

protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            Database.SetInitializer<BlogContext>(new DropCreateDatabaseAlways<BlogContext>());    

            using (var context = new BlogContext())
            {
                context.Database.Initialize(force: true);
            }    
        }

2 つのアクションを持つDatabaseControllerという新しいコントローラーを作成します。

Accessアクションでは、DB を削除し、以前に削除された DB を作成した場所からRecreateアクションにリダイレクトします。

namespace DeleteDBOnEveryRequest.Controllers
{
    public class DatabaseController : Controller
    {
        public ActionResult Access()
        {
            using (var context = new BlogContext())
            {
                context.Database.Delete();
            } 
            return RedirectToAction("Recreated");
        }

        public ActionResult Recreated()
        {
            using (var context = new BlogContext())
            {
                context.Database.Initialize(force: true);                
            }
            return View();
        }
    }
}

これはあなたが望んでいたものですか?

于 2012-10-08T09:13:58.030 に答える