强制code-首先总是初始化一个不存在的数据库? [英] Forcing code-first to always initialize a non-existent database?

查看:287
本文介绍了强制code-首先总是初始化一个不存在的数据库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有时候,我会删除我的开发数据库和运行我的EF code-首次应用。我会得到错误:

  

不能登录请求打开数据库AssessmentSystem。登录失败。   用户登录失败AssessmentAdmin。

我想这是因为的DbContext 只运行数据库的初始化逻辑每次当上下文用于第一次的AppDomain一次,如<一个href="http://www.$c$cguru.com/csharp/article.php/c19999/Understanding-Database-Initializers-in-Entity-Framework-$c$c-First.htm">this页面说。这意味着我需要回收IIS应用程序池获得EF,​​如果我把它重新创建我的数据库。

有没有什么办法可以让数据库初始化code运行的每次的我尝试访问数据库?因此,它总是会检查数据库是否存在,如果没有,创建,而不是试图打开它,即使它使用相同的AppDomain是previously访问,我现在已经放弃了数据库?

请注意,我想这initializtion检查要对每个查询的,所以即使有它的的Application_Start 做得还往往不够完成;理想情况下,我希望能够加载一些DB数据,删除数据库,然后装载一些DB数据,这将重新创建数据库没有我甚至无需重新启动应用程序(基本上我只需要重新加载网页,加载一些DB数据)。

解决方案

初始化程序当你需要,所以如果你想创建的应用程序启动数据库,使用以下的任何访问数据库执行:

  context.Database.Initialize(真正的); //如果设置为true,即使它已经运行初始化运行。
    context.Database.Create()
 

<一个href="http://msdn.microsoft.com/en-us/library/system.data.entity.database.initialize(v=vs.103).aspx">http://msdn.microsoft.com/en-us/library/system.data.entity.database.initialize(v=vs.103).aspx

CreateDatabaseIfNotExists IDatabaseInitializer的实施方案,将再现和任选重种子用数据的数据库仅当数据库不存在。种子数据库,创建一个派生类,并覆盖种子的方法。

  Database.SetInitializer&LT; MyContext&GT;(新CreateDatabaseIfNotExists&LT; MyContext&GT;());
 

<一个href="http://msdn.microsoft.com/en-us/library/gg679221(v=vs.103).aspx">http://msdn.microsoft.com/en-us/library/gg679221(v=vs.103).aspx

DropCreateDatabaseIfModelChanges IDatabaseInitializerthat的实现会删除,重新创建,和可选的重新播种时如果该模型已经改变,因为在创建数据库数据的数据库。这是通过写商店模型的哈希数据库创建时,然后比较该哈希值与一个从当前模型生成的实现。种子数据库,创建一个派生类,并覆盖种子的方法。

  

初​​始化策略可以选择检查数据库   存在,创建一个新的数据库,并与种子数据的数据库。该   默认的策略是一个实例   CreateDatabaseIfNotExists。

Database.SetInitializer(新DropCreateDatabaseIfModelChanges());

  

请注意,这里假设你有权限甚至删除您的数据库。

<一个href="http://msdn.microsoft.com/en-us/library/gg679604(v=vs.103).aspx">http://msdn.microsoft.com/en-us/library/gg679604(v=vs.103).aspx

DropCreateDatabaseAlways

IDatabaseInitializer的实现,这将总是重建和任选重新播种的数据库数据的第一次的上下文中使用的应用程序域。种子数据库,创建一个派生类,并覆盖种子的方法。

  Database.SetInitializer&LT; MyContext&GT;(新DropCreateDatabaseAlways&LT; MyContext&GT;());
 

<一个href="http://msdn.microsoft.com/en-us/library/gg679506(v=vs.103).aspx">http://msdn.microsoft.com/en-us/library/gg679506(v=vs.103).aspx

我建议你看看迁移如果你想跟踪,恢复你到你的数据库向previous状态的改变<一href="http://msdn.microsoft.com/hr-hr/data/jj591621">http://msdn.microsoft.com/hr-hr/data/jj591621

更新

  context.Database.Initialize(真正的);
 

  

如果该参数力设置为true,则初始化运行   不管它是否已被之前运行。这可以是   如果一个应用程序正在运行时,一个数据库被删除,需要有用   重新初始化。

有关MVC应用程序中添加一个节到的Application_Start()方法的Global.asax

 保护无效的Application_Start(){

     Database.SetInitializer&其中; MyContext&GT;(新DropCreateDatabaseAlways&其中; MyContext&GT;());

     //初始化力的模式的转变的数据库。
     使用(VAR上下文=新MyContext()){
          context.Database.Initialize(力:真正的);
     }
}
 

你也可以使用自定义的初始化:

 公共类MyDbInit:DropCreateDatabaseAlways&LT; MyContext&GT;
{

}
 

然后用

  Database.SetInitializer(新MyDbInit());
 

更新2

请叫一个新的空MVC4应用程序的 DeleteDBOnEveryRequest 。 将在Global.asax的Application_Start以下

 保护无效的Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

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

            Database.SetInitializer&其中; BlogContext&GT;(新DropCreateDatabaseAlways&其中; BlogContext&GT;());

            使用(VAR上下文=新BlogContext())
            {
                context.Database.Initialize(力:真正的);
            }
        }
 

请一个名为 DatabaseController 有两个动作新控制器。

访问操作删除数据库,并重定向到重建的行动从那里你创建一个数据库,因为它是previousy删除。

 命名空间DeleteDBOnEveryRequest.Controllers
{
    公共类DatabaseController:控制器
    {
        公众的ActionResult访问()
        {
            使用(VAR上下文=新BlogContext())
            {
                context.Database.Delete();
            }
            返回RedirectToAction(重建);
        }

        公众的ActionResult重建()
        {
            使用(VAR上下文=新BlogContext())
            {
                context.Database.Initialize(力:真正的);
            }
            返回查看();
        }
    }
}
 

这是你想要的?

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

Cannot open database "AssessmentSystem" requested by the login. The login failed. Login failed for user 'AssessmentAdmin'.

I think this is because the DbContext only runs the DB initialization logic "once per AppDomain when the context is used for the first time", as this page says. This means I need to recycle the IIS application pool to get EF to recreate my database if I drop it.

Is there any way I can get the DB initialization code to run every time I try to access the database? So, it will always check to see whether the DB exists and if not, create it instead of trying to open it, even if it's using the same AppDomain that previously accessed the database that I have now dropped?

Note that I would like this initializtion check to be done on every query, so even having it done in Application_Start isn't often enough; ideally, I'd like to be able to load some DB data, delete the DB, then load some DB data and it would recreate the DB without my even having to restart the application (basically I would just have to reload the web page that loads some DB data).

解决方案

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?

这篇关于强制code-首先总是初始化一个不存在的数据库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆