如何从C#恢复数据库

我有一个SQL 2008 DB。 我正在运行一个支持该数据库的表单,然后尝试更新它。 如果更新失败,则想法是恢复该备份。 这是我用来恢复备份的代码。

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时出现exception。

主要的例外是

{“服务器’localhost’的恢复失败。”}

深入研究内部exception会显示这些错误

执行Transact-SQL语句或批处理时发生exception。

然后

逻辑文件“DB”不是数据库“DB”的一部分。 使用RESTORE FILELISTONLY列出逻辑文件名。\ r \ n \ nRESTORE DATABASEexception终止。

我假设有一些方法可以告诉它只是使用替换现有的DB。

我使用这段代码来获取数据库的文件路径,以获得转储备份的目录。 也许这可以用来重新创建文件名。

 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; } 

我改变了我的备份并恢复function看起来像这样:

 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); } 

这样他们就可以使用那里的任何文件。 不再需要重定位文件和指令。

感谢Remus的回答!

我修改了

 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)); 

我的代码运行成功。

感谢您的支持!

您正在根据数据库名称添加RelocateFile选项,这是不正确的。 您应该根据重定位的每个文件的逻辑文件名添加它们。 使用Restore.ReadFileList检索逻辑文件名列表。