如何从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
检索逻辑文件名列表。