Forcing code-first to always initialize a non-existent database?

前端 未结 1 1440
花落未央
花落未央 2020-12-01 02:17

Sometimes, I\'ll delete my development database and run my EF code-first application. I\'ll get the error:

Cannot open database \"AssessmentSystem\"

相关标签:
1条回答
  • 2020-12-01 03:03

    Initializer is executed when you need to access the database so if you want to create database on app start use anything of the following:

        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 An implementation of IDatabaseInitializer that will recreate and optionally re-seed the database with data only if the database does not exist. To seed the database, create a derived class and override the Seed method.

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

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

    DropCreateDatabaseIfModelChanges An implementation of IDatabaseInitializerthat will delete, recreate, and optionally re-seed the database with data only if the model has changed since the database was created. This is achieved by writing a hash of the store model to the database when it is created and then comparing that hash with one generated from the current model. To seed the database, create a derived class and override the Seed method.

    The initialization strategy can optionally check for database existence, create a new database, and seed the database with data. The default strategy is an instance of CreateDatabaseIfNotExists.

    Database.SetInitializer(new DropCreateDatabaseIfModelChanges());

    Note that this assumes you have permission to even drop your database.

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

    DropCreateDatabaseAlways

    An implementation of IDatabaseInitializer that will always recreate and optionally re-seed the database with data the first time that a context is used in the application domain. To seed the database, create a derived class and override the Seed method.

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

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

    I recommend that you look at Migrations if you want to track, revert the changes you made to your DB to the previous state http://msdn.microsoft.com/hr-hr/data/jj591621 .

    UPDATE

    context.Database.Initialize(true);
    

    If the parameter force is set to true, then the initializer is run regardless of whether or not it has been run before. This can be useful if a database is deleted while an app is running and needs to be reinitialized.

    For MVC application add a section to the Application_Start() method in the Global.asax

    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);
         }    
    }
    

    Also you can use a custom initializer :

    public class MyDbInit : DropCreateDatabaseAlways<MyContext>
    {
    
    }
    

    and then use

    Database.SetInitializer(new MyDbInit());
    

    UPDATE 2

    Make a new empty MVC4 application called DeleteDBOnEveryRequest. Put the following in the 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);
                }    
            }
    

    Make a new controller called DatabaseController with two actions.

    In the Access action you delete the DB and redirect to Recreated action from where you create a DB as it was previousy deleted.

    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();
            }
        }
    }
    

    Is this what you wanted?

    0 讨论(0)
提交回复
热议问题