SMO恢复在完成之前不会阻塞。我没有使用Async

时间:2015-02-19 10:38:30

标签: c# sql .net smo

我正在使用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();

然后我得到以下异常:

数据库&#39; RestoredDatabase&#39;无法打开。它正处于恢复过程中。

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

我还为完整和完成百分比添加了事件处理程序并运行异步。它确实将数据库标记为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: 

数据库&#39; RestoredDatabase&#39;无法打开。它正处于恢复过程中。

1 个答案:

答案 0 :(得分:1)

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

如果你想窥视内部使用待机恢复模式。