如何从C#恢复数据库

Ant*_*y D 15 .net c# sql-server backup smo

我有一个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();
}
Run Code Online (Sandbox Code Playgroud)

问题似乎是我选择的文件名与在线数据库不同.我基本上想用备份替换服务器上的数据库.我调用SqlRestore时遇到异常.

主要的例外是

{"服务器'localhost'的恢复失败."}

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

执行Transact-SQL语句或批处理时发生异常.

然后

逻辑文件"DB"不是数据库"DB"的一部分.使用RESTORE FILELISTONLY列出逻辑文件名.\ r \n \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;
}
Run Code Online (Sandbox Code Playgroud)

Ant*_*y D 21

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

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);
}
Run Code Online (Sandbox Code Playgroud)

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

  • 如果从同一台计算机上的同一数据库的备份还原,则无需重定位文件.仅在通过备份/还原移动和复制数据库时才需要重定位. (3认同)
  • 好的,这里有一些提示:关于备份文件路径,如果文件确实存在于源文件夹中,请始终注意.关于重定位,编写mdf文件可能是一个权限问题.如果您的应用有权读取.bak文件,请注意,在这种情况下请检查SQL配置管理器:MSSQLServer服务必须在LocalSystem用户下运行. (3认同)

小智 12

感谢Remus的回答!

我修改了

sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName, dataFileLocation));
sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName + "_log", logFileLocation)); 
Run Code Online (Sandbox Code Playgroud)

这两条线来

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));
Run Code Online (Sandbox Code Playgroud)

我的代码运行成功.

感谢您的支持!


Rem*_*anu 5

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