Restoring a LocalDB within an MVC web application
UPDATE: EntityFramework 6 has lots of Resiliency enhancements, but one of the side effects is that this needs a tweak to keep EF from spinning up a transaction around the SQL statement. Essentially, you have to call ExecuteSqlCommand and request that it does NOT ensure the a transaction exists with the first parameter of TransactionalBehavior.DoNotEnsureTransaction. If still running EF 5 or below, omit that argument.
So, as a follow-up to backing up a LocalDB database, I guess I should show the simplest path to restoring one.
So, without further adéu, I give you:
This iteration saves the posted file based on the current date-time and the supplies the correct commands to restore the database. I leave the flushing of HttpCache to you...public class RestoreDatabaseModel { public HttpPostedFileBase File { get; set; } } // // GET: /Admin/RestoreDatabase [Authorize(Roles = "Admin")] public ActionResult RestoreDatabase() { return View(new RestoreDatabaseModel()); } // // POST: /Admin/RestoreDatabase [Authorize(Roles = "Admin")] [HttpPost] public ActionResult RestoreDatabase(RestoreDatabaseModel model) { const string YOURAPPNAME = "YourAppName"; var dbPath = Server.MapPath(String.Format("~/App_Data/Restore_{0}_DB_{1:yyyy-MM-dd-HH-mm-ss}.bak", YOURAPPNAME, DateTime.UtcNow)); try { model.File.SaveAs(dbPath); using (var db = new DBContext()) { var cmd = String.Format(@" USE [Master]; ALTER DATABASE {0} SET SINGLE_USER WITH ROLLBACK IMMEDIATE; RESTORE DATABASE {0} FROM DISK='{1}' WITH REPLACE; ALTER DATABASE {0} SET MULTI_USER;" , YOURAPPNAME, dbPath); db.Database.ExecuteSqlCommand(TransactionalBehavior.DoNotEnsureTransaction, cmd); } ModelState.AddModelError("", "Restored!"); } catch (Exception ex) { ModelState.AddModelError("", ex); } return View(model); }
Also, if you haven't extended the upload limits of a POST, you'll need this (or similar) in your web.config
This enables larger files to be uploaded (in this case, 40MB... if your database backup is bigger than that, you have no business hacking around with a LocalDB... get a real SQL Server instance to point at.<system.web> <httpRuntime maxRequestLength="40960" targetFramework="4.5"> </httpRuntime> </system.web>
No comments:
Post a Comment