Cannot open database “AssessmentSystem” requested by the login. The login Failed.
Login Failed for user ‘AssessmentAdmin’.
我认为这是因为DbContext只运行数据库初始化逻辑“AppDomain每次首次使用上下文”,如this page所示。这意味着我需要回收IIS应用程序池以使EF重新创建我的数据库,如果我删除它。
有没有办法我可以得到DB初始化代码运行每次我尝试访问数据库?所以,它将始终检查数据库是否存在,如果不存在,创建它,而不是尝试打开它,即使它使用相同的AppDomain以前访问了我现在删除的数据库?
请注意,我希望对每个查询都进行这个初始化检查,所以即使在Application_Start中完成它也不够用;理想情况下,我想要加载一些数据库数据,删除数据库,然后加载一些数据库数据,它将重新创建数据库,而我甚至不需要重新启动应用程序(基本上我只需要重新加载网页,加载一些DB数据)。
解决方法
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的一个实现,只有当数据库创建以来模型发生变化时,才会删除,重新创建和可选地重新种子数据库。这是通过在创建数据库时将商店模型的哈希写入数据库,然后将该哈希与从当前模型生成的哈希进行比较来实现的。要种数据库,创建一个派生类并覆盖种子方法。
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
首次在应用程序域中使用上下文时,将始终重新创建数据库并使用数据重新种子数据库的IDatabaseInitializer的实现。要种数据库,创建一个派生类并覆盖种子方法。
Database.SetInitializer<MyContext>(new DropCreateDatabaseAlways<MyContext>());
http://msdn.microsoft.com/en-us/library/gg679506(v=vs.103).aspx
我建议您查看Migrations如果要跟踪,将您对DB的更改还原到先前的状态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.
对于MVC应用程序,在Global.asax中的Application_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); } }
创建一个名为DatabaseController的新控制器,具有两个操作。
在Access操作中,您删除数据库并重定向到创建数据库的Recreated操作,因为它已被删除。
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(); } } }
这是你想要的吗?