SMO Restore 在完成之前不会阻塞。我没有使用异步

SMO Restore not blocking until complete. I am not using Async

我正在使用 SMO sdk 来恢复数据库。在还原完成之前,sqlRestore 方法不会阻塞。我已经通过尝试在恢复后直接访问正在恢复的数据库来对此进行了测试,但我收到了数据库正在恢复的错误消息。我试过调用等待函数。

我的代码如下:

        Server sqlServer = new Server("reddsql01");

        Restore dbRestore = new Restore();
        dbRestore.Devices.AddDevice(@"Z:\Test Folder\database.bak", DeviceType.File);
        dbRestore.Database = "RestoredDatabase";
        dbRestore.NoRecovery = true;


        foreach (DataRow dRow in dbRestore.ReadFileList(sqlServer).Rows)
        {
            string logicalFileName = dRow["LogicalName"] as string;
            string physicalFileName = dRow["PhysicalName"] as string;

            dbRestore.RelocateFiles.Add(new RelocateFile(logicalFileName, (Path.GetExtension(physicalFileName) == ".mdf" ? @"D:\Data\" : @"L:\Log\") + dbRestore.Database));
        }
        dbRestore.ReplaceDatabase = true;


        dbRestore.SqlRestore(sqlServer);
        dbRestore.Wait();

        Database restoredDB = sqlServer.Databases[dbRestore.Database];
        for (int i = 0; i < restoredDB.Tables.Count; i++)
        {
            Console.WriteLine(restoredDB.Tables[i].Name);
        }

        Console.ReadLine();

然后我得到以下异常:

无法打开数据库 'RestoredDatabase'。正在恢复中。

有人可以帮忙吗。我可以写一些粗略的东西来循环检查数据库是否已经完成恢复,但更喜欢一个简洁的解决方案。

我还向完成和完成百分比以及 运行 异步添加了事件处理程序。它确实将数据库标记为 100% 已恢复。

完全异常:

    Microsoft.SqlServer.Management.Common.ExecutionFailureException was unhandled
  HResult=-2146233087
  Message=An exception occurred while executing a Transact-SQL statement or batch.
  Source=Microsoft.SqlServer.ConnectionInfo
  StackTrace:
       at Microsoft.SqlServer.Management.Common.ServerConnection.ExecuteNonQuery(String sqlCommand, ExecutionTypes executionType)
       at Microsoft.SqlServer.Management.Smo.ExecuteSql.ExecuteImmediate(String query)
       at Microsoft.SqlServer.Management.Smo.ExecuteSql.GetDataProvider(StringCollection query, Object con, StatementBuilder sb, RetriveMode rm)
       at Microsoft.SqlServer.Management.Smo.ExecuteSql.GetDataProvider(StringCollection query, Object con, StatementBuilder sb)
       at Microsoft.SqlServer.Management.Smo.SqlObjectBase.FillData(ResultType resultType, StringCollection sql, Object connectionInfo, StatementBuilder sb)
       at Microsoft.SqlServer.Management.Smo.SqlObjectBase.FillDataWithUseFailure(SqlEnumResult sqlresult, ResultType resultType)
       at Microsoft.SqlServer.Management.Smo.SqlObjectBase.BuildResult(EnumResult result)
       at Microsoft.SqlServer.Management.Smo.SqlObjectBase.GetData(EnumResult erParent)
       at Microsoft.SqlServer.Management.Sdk.Sfc.Environment.GetData()
       at Microsoft.SqlServer.Management.Sdk.Sfc.Environment.GetData(Request req, Object ci)
       at Microsoft.SqlServer.Management.Sdk.Sfc.Enumerator.GetData(Object connectionInfo, Request request)
       at Microsoft.SqlServer.Management.Smo.ExecutionManager.GetEnumeratorDataReader(Request req)
       at Microsoft.SqlServer.Management.Smo.SqlSmoObject.InitChildLevel(Urn levelFilter, ScriptingPreferences sp, Boolean forScripting)
       at Microsoft.SqlServer.Management.Smo.SqlSmoObject.InitChildLevel(Urn levelDescription, ScriptingPreferences sp)
       at Microsoft.SqlServer.Management.Smo.SmoCollectionBase.InitializeChildCollection(Boolean refresh)
       at Microsoft.SqlServer.Management.Smo.SmoCollectionBase.InitializeChildCollection()
       at Microsoft.SqlServer.Management.Smo.SmoCollectionBase.get_Count()
       at ConsoleApplication10.Program.Main(String[] args) in c:\Users\Darren.West\Documents\Visual Studio 2013\Projects\ConsoleApplication10\ConsoleApplication10\Program.cs:line 57
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: System.Data.SqlClient.SqlException
       HResult=-2146232060
       Message=Database 'RestoredDatabase' cannot be opened. It is in the middle of a restore.
       Source=.Net SqlClient Data Provider
       ErrorCode=-2146232060
       Class=14
       LineNumber=1
       Number=927
       Procedure=""
       Server=reddsql01
       State=2
       StackTrace:
            at Microsoft.SqlServer.Management.Common.ConnectionManager.ExecuteTSql(ExecuteTSqlAction action, Object execObject, DataSet fillDataSet, Boolean catchException)
            at Microsoft.SqlServer.Management.Common.ServerConnection.ExecuteNonQuery(String sqlCommand, ExecutionTypes executionType)
       InnerException: 

无法打开数据库 'RestoredDatabase'。正在恢复中。

您正在设置 NoRecovery = true。这就是为什么数据库永远不会离开恢复状态而无法读取的原因。

如果您想查看内部情况,请使用待机恢复模式。