这是我的问题,我在C#中有一个恢复功能,由这个答案指导:
SMO: restoring to a different DB
但是当程序试图执行此代码db.SetOnline();
时,它会抛出异常:Object reference not set to an instance of an object.
。问题是...... db对象为null。但为什么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);
}
}
答案 0 :(得分:1)
我认为DB resore的过程是异步的。因此,如果您尝试在恢复后立即获取数据库,则db可能处于中间恢复状态,并且不能通过SMO获得。因此,您应该尝试等待/拉取db将在sql server中创建/ resotred并且可以通过SMO获得。例如,您可以添加以下代码而不是db = srvr.Databases [baseDatosDestino]:
while( ( db = srvr.Databases[baseDatosDestino] ) == null )
{
Thread.Sleep(10);
}
答案 1 :(得分:0)
使用SQL Server数据库还原向导还原数据库时,我看到了此问题。当SQL Server的目标版本低于SQL Server的源版本时,会发生这种情况。因此,您可能会尝试将数据库备份从SQL Server 2012还原为旧版本(如2008R2)。因此,请确认目标版本与源数据库相同或更高。