public SqlExecutionResult <string> Restore(string sourcePath, int version = 3, bool preventActionToBegin = false) { this.TraceDebug("Restauration d'un backup de base de données..."); CreateSqlDirForDebugPurpose(); SqlConnection sqlConn = CreateAdminSqlConnection(true); SqlCommand sqlCmd; var task = new Task <string>(() => { try { // On retrouve l'emplacement de la nouvelle base SqlDataReader reader; sqlCmd = new SqlCommand($@"SELECT physical_name FROM sys.master_files WHERE physical_name LIKE '%\{Const.DataBaseName_v3}.mdf'", sqlConn); sqlConn.Open(); reader = sqlCmd.ExecuteReader(); if (!reader.Read()) { throw new Exception("Impossible de retrouver l'emplacement de la nouvelle base de donnée."); } string newDbPath = Directory.GetParent((string)reader[0]).FullName; sqlConn.Close(); // On récupère la version de la nouvelle base sqlCmd = new SqlCommand($"USE [{Const.DataBaseName_v3}]", sqlConn); sqlConn.Open(); sqlCmd.ExecuteNonQuery(); sqlCmd = new SqlCommand("GetDatabaseVersion", sqlConn) { CommandType = System.Data.CommandType.StoredProcedure }; reader = sqlCmd.ExecuteReader(); if (!reader.Read()) { throw new Exception("Impossible de retrouver la version de la nouvelle base de donnée."); } Version newDbVersion = Version.Parse((string)reader[0]); sqlConn.Close(); //On coupe toutes les connexions à la base en la passant en single user sqlCmd = new SqlCommand($"ALTER DATABASE [{Const.DataBaseName_v3}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE", sqlConn); sqlConn.Open(); sqlCmd.ExecuteNonQuery(); sqlConn.Close(); // On supprime la nouvelle base var deleteText = $@"IF EXISTS(SELECT * FROM sysdatabases WHERE name='{Const.DataBaseName_v3}') DROP DATABASE [{Const.DataBaseName_v3}]"; sqlCmd = new SqlCommand(deleteText, sqlConn); this.TraceDebug("Suppression de la base"); this.TraceDebug(deleteText); sqlConn.Open(); sqlCmd.ExecuteNonQuery(); sqlConn.Close(); // On restaure le backup dans la nouvelle instance string restoreCmdText; // On récupère les noms logiques du backup restoreCmdText = $@"RESTORE FILELISTONLY FROM DISK=N'{sourcePath}'"; sqlCmd = new SqlCommand(restoreCmdText, sqlConn); this.TraceDebug("Restauration de la base (récupération des noms logiques)"); this.TraceDebug(restoreCmdText); sqlConn.Open(); var dataReader = sqlCmd.ExecuteReader(); string LogicalNameDb = ""; string LogicalNameLog = ""; while (dataReader.Read()) { string logicalName = (string)dataReader["LogicalName"]; string type = (string)dataReader["Type"]; if (type == "D") { LogicalNameDb = logicalName; } else if (type == "L") { LogicalNameLog = logicalName; } } sqlConn.Close(); this.TraceDebug($"Db : {LogicalNameDb}, Log : {LogicalNameLog}"); restoreCmdText = $@"RESTORE DATABASE [{Const.DataBaseName_v3}] FROM DISK=N'{sourcePath}' WITH MOVE '{LogicalNameDb}' TO '{newDbPath}\{Const.DataBaseName_v3}.mdf', MOVE '{LogicalNameLog}' TO '{newDbPath}\{Const.DataBaseName_v3}.LDF'"; sqlCmd = new SqlCommand(restoreCmdText, sqlConn); this.TraceDebug("Restauration de la base"); this.TraceDebug(restoreCmdText); sqlConn.Open(); sqlCmd.ExecuteNonQuery(); sqlConn.Close(); // On effectue l'upgrade jusqu'à la version de l'installeur this.TraceDebug($"Update de la base vers {newDbVersion}"); Scripts.GoTo(sqlConn, newDbVersion); // On restore les droits utilisateurs sur la base this.TraceDebug($"Restauration des droits utilisateurs"); Scripts.Execute(sqlConn, "RestoreUserRights"); } catch (Exception e) { this.TraceError("Erreur pendant l'execution du script sql de restauration", e); throw e; } return(sourcePath); }); if (!preventActionToBegin) { task.Start(); } return(SqlExecutionResult.New(sqlConn, task)); }