2016-08-24 9 views
9

これは私の問題で、私はこの答えによって導かC#で機能を回復している:SMO:別のDBに復元する理由、なぜdbがnullですか?

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

を 'デシベル= srvr.Databases [baseDatosDestino] ''前にdbオブジェクトのヌルましたか?そうでない場合、 'srvr.Databases [baseDatosDestino]'オブジェクトはnullでなければなりません。 –

+0

'srvr.Databases [baseDatosDestino]'は32行と50行の2つの呼び出しを持っていますが、50行目のオブジェクト "db"はNULLです。なぜですか? ...またはなぜ 'srvr.Databases [baseDatosDestino]'がNULLですか? –

+0

私は 'srvr.Databases [baseDatosDestino]'がヌルであってはならないと思います –

答えて

0

SQL Serverデータベースを復元ウィザード使用してデータベースを復元するとき、私はこの問題を見てきました。これは、SQL Serverの移行先バージョンがSQL Serverの移行元バージョンよりも低い場合に発生します。したがって、SQL Server 2012から2008R2などの古いバージョンにデータベースバックアップを復元しようとしている可能性があります。ソース・データベースと同じか、それ以上のバージョンがあることを確認してください。

0

DB resoreのプロセスは非同期だと思います。したがって、復元後すぐにDBを取得しようとすると、dbは中間の復元状態になり、SMOでは使用できなくなります。したがって、dbはSQL Serverで作成/再作成され、SMOを通じて使用可能になりますが、待機/プルしようとする必要があります。たとえば、あなたはfolowingコードの代わりに、デシベル= srvr.Databases [baseDatosDestino]を追加することができます

while((db = srvr.Databases[baseDatosDestino]) == null) 
{ 
    Thread.Sleep(10); 
} 
関連する問題