Как восстановить базу данных с С#

У меня есть база данных SQL 2008. Я запускаю форму, которая поддерживает этот БД, затем пытается его обновить. Если обновление не работает, идея состоит в том, чтобы восстановить эту резервную копию. Вот код, который я использую для восстановления резервной копии.

public void RestoreDatabase(String databaseName, String backUpFile, String serverName, String userName, String password)
{
    Restore sqlRestore = new Restore();
    BackupDeviceItem deviceItem = new BackupDeviceItem(backUpFile, DeviceType.File);
    sqlRestore.Devices.Add(deviceItem);
    sqlRestore.Database = databaseName;
    ServerConnection connection = new ServerConnection(serverName, userName, password);
    Server sqlServer = new Server(connection);
    sqlRestore.Action = RestoreActionType.Database;

    string logFile = System.IO.Path.GetDirectoryName(backUpFile);
    logFile = System.IO.Path.Combine(logFile, databaseName + "_Log.ldf");

    string dataFile = System.IO.Path.GetDirectoryName(backUpFile);
    dataFile = System.IO.Path.Combine(dataFile, databaseName + ".mdf");

    Database db = sqlServer.Databases[databaseName];
    RelocateFile rf = new RelocateFile(databaseName, dataFile);
    sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName, dataFile));
    sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName + "_log", logFile));
    sqlRestore.SqlRestore(sqlServer);
    db = sqlServer.Databases[databaseName];
    db.SetOnline();
    sqlServer.Refresh();
}

Проблема заключается в том, что имена файлов, которые я выбираю, отличаются от онлайн-БД. Я в основном хочу заменить базу данных на сервере резервной копией. Я получаю исключение, когда я вызываю SqlRestore.

Основное исключение говорит

{ "Сбой восстановления для сервера" Локальный "." }

Копание во внутренние исключения показывает эти ошибки

При выполнении исключения оператор Transact-SQL или пакет.

а затем

Логический файл "DB" не является частью база данных "БД". Использовать ВОССТАНОВЛЕНИЕ FILELISTONLY для отображения логического файла имена. \r\nRESTORE DATABASE завершение аномально.

Я предполагаю, что есть какой-то способ сказать это просто использовать замену существующей БД как есть.

Я использую этот бит кода, чтобы получить путь к файлу базы данных, чтобы создать резервную копию каталога. Возможно, это может быть использовано для восстановления имен файлов.

public string GetDBFilePath(String databaseName, String userName, String password, String serverName)
{
    ServerConnection connection = new ServerConnection(serverName, userName, password);
    Server sqlServer = new Server(connection);
    Database db = sqlServer.Databases[databaseName];
    return sqlServer.Databases[databaseName].PrimaryFilePath;
}

Ответы

Ответ 1

Я изменил резервную копию и восстановил функции так:

public void BackupDatabase(SqlConnectionStringBuilder csb, string destinationPath)
{
    ServerConnection connection = new ServerConnection(csb.DataSource, csb.UserID, csb.Password);
    Server sqlServer = new Server(connection);

    Backup bkpDatabase = new Backup();
    bkpDatabase.Action = BackupActionType.Database;
    bkpDatabase.Database = csb.InitialCatalog;
    BackupDeviceItem bkpDevice = new BackupDeviceItem(destinationPath, DeviceType.File);
    bkpDatabase.Devices.Add(bkpDevice);
    bkpDatabase.SqlBackup(sqlServer);
    connection.Disconnect();

}

public void RestoreDatabase(String databaseName, String backUpFile, String serverName, String userName, String password)
{
    ServerConnection connection = new ServerConnection(serverName, userName, password);
    Server sqlServer = new Server(connection);
    Restore rstDatabase = new Restore();
    rstDatabase.Action = RestoreActionType.Database;
    rstDatabase.Database = databaseName;
    BackupDeviceItem bkpDevice = new BackupDeviceItem(backUpFile, DeviceType.File);
    rstDatabase.Devices.Add(bkpDevice);
    rstDatabase.ReplaceDatabase = true;
    rstDatabase.SqlRestore(sqlServer);
}

Таким образом, они просто используют любые файлы. Больше нет и директив для перемещения файлов.

Ответ 2

Спасибо Ремусу за ваш ответ!

Я изменил

sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName, dataFileLocation));
sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName + "_log", logFileLocation)); 

эти две строки на

System.Data.DataTable logicalRestoreFiles = sqlRestore.ReadFileList(sqlServer);
sqlRestore.RelocateFiles.Add(new RelocateFile(logicalRestoreFiles.Rows[0][0].ToString(), dataFileLocation));
sqlRestore.RelocateFiles.Add(new RelocateFile(logicalRestoreFiles.Rows[1][0].ToString(), logFileLocation));

и мой код работает успешно.

Спасибо за поддержку!

Ответ 3

Вы добавляете параметры RelocateFile на основе имени базы данных, это неверно. Вы должны добавить их на основе логического имени файла для каждого перемещенного файла. Используйте Restore.ReadFileList, чтобы получить список логических имен файлов.