diff --git a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/ObjectExplorerService.cs b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/ObjectExplorerService.cs
index a99a1989..72cee108 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/ObjectExplorerService.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/ObjectExplorer/ObjectExplorerService.cs
@@ -12,6 +12,7 @@ using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using Microsoft.Data.Tools.Sql.DesignServices.TableDesigner;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlTools.Extensibility;
using Microsoft.SqlTools.Hosting;
@@ -23,6 +24,7 @@ using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Contracts;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel;
using Microsoft.SqlTools.ServiceLayer.SqlContext;
+using Microsoft.SqlTools.ServiceLayer.TableDesigner;
using Microsoft.SqlTools.ServiceLayer.Utility;
using Microsoft.SqlTools.ServiceLayer.Workspace;
using Microsoft.SqlTools.Utility;
@@ -381,6 +383,27 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectExplorer
TreeNode node = session.Root.FindNodeByPath(nodePath);
ExpandResponse response = null;
+ // Performance Optimization for table designer to load the database model earlier based on user configuration.
+ if (node.NodeTypeId == NodeTypes.Database && TableDesignerService.Instance.Settings.PreloadDatabaseModel)
+ {
+ // The operation below are not blocking, but just in case, wrapping it with a task run to make sure it has no impact on the node expansion time.
+ var _ = Task.Run(() =>
+ {
+ try
+ {
+ var builder = ConnectionService.CreateConnectionStringBuilder(session.ConnectionInfo.ConnectionDetails);
+ builder.InitialCatalog = node.NodeValue;
+ builder.ApplicationName = TableDesignerService.TableDesignerApplicationName;
+ var azureToken = session.ConnectionInfo.ConnectionDetails.AzureAccountToken;
+ TableDesignerCacheManager.StartDatabaseModelInitialization(builder.ToString(), azureToken);
+ }
+ catch (Exception ex)
+ {
+ Logger.Write(TraceEventType.Warning, $"Failed to start database initialization for table designer: {ex.Message}");
+ }
+ });
+ }
+
// This node was likely returned from a different node provider. Ignore expansion and return an empty array
// since we don't need to add any nodes under this section of the tree.
if (node == null)
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SqlContext/SqlToolsSettingsValues.cs b/src/Microsoft.SqlTools.ServiceLayer/SqlContext/SqlToolsSettingsValues.cs
index ce92841f..d505b92f 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/SqlContext/SqlToolsSettingsValues.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/SqlContext/SqlToolsSettingsValues.cs
@@ -22,6 +22,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlContext
IntelliSense = new IntelliSenseSettings();
QueryExecutionSettings = new QueryExecutionSettings();
Format = new FormatterSettings();
+ TableDesigner = new TableDesignerSettings();
}
}
@@ -48,5 +49,11 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlContext
///
[JsonProperty("objectExplorer")]
public ObjectExplorerSettings ObjectExplorer { get; set; }
+
+ ///
+ /// Gets or sets the table designer settings
+ ///
+ [JsonProperty("tableDesigner")]
+ public TableDesignerSettings TableDesigner { get; set; }
}
}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/SqlContext/TableDesignerSettings.cs b/src/Microsoft.SqlTools.ServiceLayer/SqlContext/TableDesignerSettings.cs
new file mode 100644
index 00000000..b252843f
--- /dev/null
+++ b/src/Microsoft.SqlTools.ServiceLayer/SqlContext/TableDesignerSettings.cs
@@ -0,0 +1,18 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+namespace Microsoft.SqlTools.ServiceLayer.SqlContext
+{
+ ///
+ /// Contract for receiving table designer settings as part of workspace settings
+ ///
+ public class TableDesignerSettings
+ {
+ ///
+ /// Whether the database model should be preloaded to make the initial launch quicker.
+ ///
+ public bool PreloadDatabaseModel { get; set; } = false;
+ }
+}
diff --git a/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/TableDesignerService.cs b/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/TableDesignerService.cs
index 8ee9b1ef..77640139 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/TableDesignerService.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/TableDesigner/TableDesignerService.cs
@@ -14,6 +14,7 @@ using Microsoft.Data.Tools.Sql.DesignServices;
using Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts;
using Dac = Microsoft.Data.Tools.Sql.DesignServices.TableDesigner;
using STSHost = Microsoft.SqlTools.ServiceLayer.Hosting.ServiceHost;
+using Microsoft.SqlTools.ServiceLayer.SqlContext;
namespace Microsoft.SqlTools.ServiceLayer.TableDesigner
{
@@ -32,6 +33,8 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner
{
}
+ public TableDesignerSettings Settings { get; private set; } = new TableDesignerSettings();
+
///
/// Gets the singleton instance object
///
@@ -61,7 +64,16 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner
this.ServiceHost.SetRequestHandler(GenerateScriptRequest.Type, HandleGenerateScriptRequest);
this.ServiceHost.SetRequestHandler(GeneratePreviewReportRequest.Type, HandleGeneratePreviewReportRequest);
this.ServiceHost.SetRequestHandler(DisposeTableDesignerRequest.Type, HandleDisposeTableDesignerRequest);
+ Workspace.WorkspaceService.Instance.RegisterConfigChangeCallback(UpdateSettings);
+
}
+
+ internal Task UpdateSettings(SqlToolsSettings newSettings, SqlToolsSettings oldSettings, EventContext eventContext)
+ {
+ Settings.PreloadDatabaseModel = newSettings.MssqlTools.TableDesigner.PreloadDatabaseModel;
+ return Task.FromResult(0);
+ }
+
private Task HandleRequest(RequestContext requestContext, Func action)
{
// The request handling will take some time to return, we need to use a separate task to run the request handler so that it won't block the main thread.