2016-08-24 12 views
9

Bu benim sorunum, ben bu cevapları rehberliğinde C# bir geri yükleme fonksiyonu var:SMO: farklı bir DB'ye geri yükleme, neden db boş?

SMO: restoring to a different DB

Ama program bu kodu db.SetOnline(); yürütmeye çalıştığında bir istisna atar: Object reference not set to an instance of an object.. Sorun şu ki ... db nesnesi boş. Ama neden db nesnesi NULL? SQL Server veritabanı geri yükleme sihirbazı kullanarak bir veritabanını geri yüklerken bu sorunu gördük

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

'db = srvr.Databases [baseDatosDestino] '' önce db nesnesi boş oldu mu? Değilse o zaman 'srvr.Databases [baseDatosDestino]' nesnesinin boş olması gerekir. –

+0

'srvr.Databases [baseDatosDestino]' satırda 2 çağrı var: 32 ve 50, ancak sadece 50 satırında nesne "db" NULL, neden? ... VEYA neden 'srvr.Databases [baseDatosDestino]' NULL nedir? –

+0

Sanırım "srvr.Databases [baseDatosDestino]" null –

cevap

0

:

Bu

benim fonksiyondur. SQL Server'ın hedef sürümü, SQL Server'ın Kaynak sürümünden daha düşük olduğunda oluşur. Belki de veritabanı yedeklemesini SQL Server 2012'den 2008R2 gibi eski bir sürümüne geri yüklemeye çalışacaksınız. Dolayısıyla, Hedef sürümün kaynak veritabanıyla aynı veya daha yüksek olduğunu onaylayın.

0

DB yeniden işleyişinin asenkron olduğunu düşünüyorum. Bu nedenle, geri yüklemeden hemen sonra DB almayı denerseniz, db orta geri yükleme durumunda olabilir ve SMO aracılığıyla kullanılamaz. Bu yüzden db, sql sunucusunda oluşturulacak/yeniden kaydedilecek ve SMO aracılığıyla sunulacakken beklemeyi/çekmeyi denemelisiniz. Örneğin yerine db kodunu folowing ekleyebilir = srvr.Databases [baseDatosDestino]:

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