SMO:恢复到另一个DB,为什么DB为空

本文关键字:DB 为空 为什么 另一个 恢复 SMO | 更新日期: 2023-09-27 18:04:00

这是我的问题,我在c#中有一个恢复函数,由这个答案指导:

SMO:恢复到另一个DB

但是当程序试图执行这段代码db.SetOnline();时,它抛出了一个异常:Object reference not set to an instance of an object.。问题是……Db对象为空。但是为什么db对象是NULL?

这是我的功能

public void restaurarBackup(string baseDatosDestino, string rutaBackUp, Server srvr)
{
    try
    {
        if (System.IO.Directory.Exists(DBpath))
        {
            // Si el usuario ha elegido el archivo desde el que quiere que la base de datos para ser restaurado
            // Crear una nueva base de datos de la operación de restauración
            Restore rstDatabase = new Restore();
            // Set the backup device from which we want to restore, to a file
            BackupDeviceItem bkpDevice = new BackupDeviceItem(DBpath + rutaBackUp, DeviceType.File);
            // Add the backup device to the restore type
            rstDatabase.Devices.Add(bkpDevice);
            // Set the database that we want to perform the restore on
            rstDatabase.Database = baseDatosDestino;
            DataTable dtFileList = rstDatabase.ReadFileList(srvr);
            string mdf_logicalFileName = dtFileList.Rows[0][0].ToString();
            string mdf_PhysicalFileName = String.Format(@"{0}'{1}.mdf", srvr.Information.MasterDBPath, baseDatosDestino);
            string ldf_logicalFileName = dtFileList.Rows[1][0].ToString();
            string ldf_PhysicalFileName = String.Format(@"{0}'{1}_log.ldf", srvr.Information.MasterDBPath, baseDatosDestino);
            rstDatabase.RelocateFiles.Add(new RelocateFile(mdf_logicalFileName, mdf_PhysicalFileName));
            rstDatabase.RelocateFiles.Add(new RelocateFile(ldf_logicalFileName, ldf_PhysicalFileName));
            srvr.KillAllProcesses(rstDatabase.Database);
            rstDatabase.Wait();
            Database db = srvr.Databases[rstDatabase.Database];
            if (db != null)
            {
                db.DatabaseOptions.UserAccess = DatabaseUserAccess.Single;
                db.Alter(TerminationClause.RollbackTransactionsImmediately);
                srvr.DetachDatabase(rstDatabase.Database, false);
            }
            // Set the restore type to a database restore
            rstDatabase.Action = RestoreActionType.Database;
            // If the database already exists, replace it
            rstDatabase.ReplaceDatabase = true;
            rstDatabase.NoRecovery = false;
            // Perform the restore
            rstDatabase.SqlRestore(srvr);
            db = srvr.Databases[baseDatosDestino];
            db.SetOnline(); // In this line the db object is null, why?
            db.DatabaseOptions.UserAccess = DatabaseUserAccess.Multiple;
            srvr.Refresh();
        }
        else
        {
            _infoError = "Verifique la existencia de la ruta de donde se va a restaurar el Backup!";
        }
    }
    catch (Exception e)
    {
        ManejoExcepcion.RegistrarExcepcion(e, out _infoError);
    }
}

SMO:恢复到另一个DB,为什么DB为空

我认为DB资源的进程是异步的。因此,如果您试图在恢复后立即获得DB,那么DB可能处于恢复中期状态,无法通过SMO使用。因此,您应该尝试等待/拉,而db将在sql server中创建/解析,并将通过SMO可用。例如,您可以添加以下代码而不是db = srvr。数据库(baseDatosDestino):

while( ( db = srvr.Databases[baseDatosDestino] ) == null ) 
{
    Thread.Sleep(10);
}

我在使用SQL Server数据库恢复向导恢复数据库时看到了这个问题。当SQL Server的目标版本低于SQL Server的源版本时,会发生这种情况。因此,也许您将尝试将数据库备份从SQL Server 2012恢复到旧版本(如2008R2)。因此,请确认目标版本与源数据库相同或更高。