diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/DatabaseTreeNode.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/DatabaseTreeNode.cs index 78d7b7ea..1fccba1a 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/DatabaseTreeNode.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/SmoModel/DatabaseTreeNode.cs @@ -19,21 +19,30 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { Parent = serverNode; NodeValue = databaseName; - Database db = new Database(serverNode.GetContextAs().Server, this.NodeValue); + var db = new Database(serverNode.GetContextAs().Server, this.NodeValue); db.Refresh(); + // If we got this far, the connection is valid. However, it's possible + // the user connected directly to the master of a readable secondary + // In that case, the name in the connection string won't be found in sys.databases + // We detect that here and fall back to master + if (db.State == SqlSmoState.Creating) + { + db = new Database(serverNode.GetContextAs().Server, "master"); + db.Refresh(); + } CacheInfoFromModel(db); } /// - /// Initializes the context and ensures that + /// Initializes the context and sets its ValidFor property /// protected override void EnsureContextInitialized() { if (context == null) { base.EnsureContextInitialized(); - Database db = SmoObject as Database; - if (context != null && db != null) + var db = SmoObject as Database; + if (db != null) { context.Database = db; } @@ -43,8 +52,8 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel protected override void PopulateChildren(bool refresh, string name, CancellationToken cancellationToken) { - SmoQueryContext context = this.GetContextAs(); - if (IsAccessible(context)) + var smoQueryContext = this.GetContextAs(); + if (IsAccessible(smoQueryContext)) { base.PopulateChildren(refresh, name, cancellationToken); } @@ -53,7 +62,7 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel if (string.IsNullOrEmpty(ErrorMessage)) { // Write error message if it wasn't already set during IsAccessible check - ErrorMessage = string.Format(CultureInfo.InvariantCulture, SR.DatabaseNotAccessible, context.Database.Name); + ErrorMessage = string.Format(CultureInfo.InvariantCulture, SR.DatabaseNotAccessible, this.NodeValue); } } } @@ -62,15 +71,11 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel { try { - if (context == null || context.Database == null) - { - return true; - } - return context.Database.IsAccessible; + return context?.Database == null || context.Database.IsAccessible; } catch (Exception ex) { - string error = string.Format(CultureInfo.InvariantCulture, "Failed to get IsAccessible. error:{0} inner:{1} stacktrace:{2}", + var error = string.Format(CultureInfo.InvariantCulture, "Failed to get IsAccessible. error:{0} inner:{1} stacktrace:{2}", ex.Message, ex.InnerException != null ? ex.InnerException.Message : "", ex.StackTrace); Logger.Write(TraceEventType.Error, error); ErrorMessage = ex.Message;