public async Task<WorkspaceNameModel> GetWorkspaceNameAsync(int workspaceID)
		{
			WorkspaceNameModel model;

			try
			{
				// Use the dependency injected IHelper to get a database connection.
				// In this example a query is being made for the name of a workspace from the workspaceID.
				// Note: async/await and ConfigureAwait(false) is used when making calls external to the service.
				//       See https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/
				//       See also https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.configureawait
				//       See also https://blogs.msdn.microsoft.com/benwilli/2017/02/09/an-alternative-to-configureawaitfalse-everywhere/
				//       See also https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
				//       Warning: Improper use of the tasks can cause deadlocks and performance issues within an application.
				string workspaceName = await _helper.GetDBContext(workspaceID).ExecuteScalarAsync<string>(new ContextQuery()
				{
					SqlStatement = "SELECT [TextIdentifier] FROM [EDDSDBO].[Artifact] WHERE [ArtifactTypeID] = 8"
				}).ConfigureAwait(false);

				model = new WorkspaceNameModel
				{
					Name = workspaceName
				};
			}
			catch (Exception exception)
			{
				// Note: logging templates should never use interpolation! Doing so will cause memory leaks. 
				_logger.LogWarning(exception, "Could not read workspace {WorkspaceID}.", workspaceID);

				// Throwing a user defined exception with a 404 status code with an additional custom FaultSafe object.
				throw new WorkspaceNameException($"Workspace {workspaceID} not found.")
				{
					FaultSafeObject = new WorkspaceNameException.FaultSafeInfo()
					{
						Information = $"Workspace {workspaceID}",
						Time = DateTime.Now
					}
				};
			}

			return model;
		}
		public async Task<List<WorkspaceNameModel>> QueryWorkspaceByNameAsync(string queryString, int limit)
		{
			var models = new List<WorkspaceNameModel>();

			// Create a Kepler service proxy to interact with other Kepler services.
			// Use the dependency injected IHelper to create a proxy to an external service.
			// This proxy will execute as the currently logged in user. (ExecutionIdentity.CurrentUser)
			// Note: If calling methods within the same service the proxy is not needed. It is doing so
			//       in this example only as a demonstration of how to call other services.
			var proxy = _helper.GetServicesManager().CreateProxy<IWorkspaceName>(ExecutionIdentity.CurrentUser);

			// Validate queryString and throw a ValidationException (HttpStatusCode 400) if the string does not meet the validation requirements.
			if (string.IsNullOrEmpty(queryString) || queryString.Length > 50)
			{
				// ValidationException is in the namespace Relativity.Services.Exceptions and found in the Relativity.Kepler.dll.
				throw new ValidationException($"{nameof(queryString)} cannot be empty or grater than 50 characters.");
			}

			try
			{
				// Use the dependency injected IHelper to get a database connection.
				// In this example a query is made for all workspaces that are like the query string.
				// Note: async/await and ConfigureAwait(false) is used when making calls external to the service.
				//       See https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/
				//       See also https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.configureawait
				//       See also https://blogs.msdn.microsoft.com/benwilli/2017/02/09/an-alternative-to-configureawaitfalse-everywhere/
				//       See also https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
				//       Warning: Improper use of the tasks can cause deadlocks and performance issues within an application.
				var workspaceIDs = await _helper.GetDBContext(-1).ExecuteEnumerableAsync(
					new ContextQuery
					{
						SqlStatement = @"SELECT TOP (@limit) [ArtifactID] FROM [Case] WHERE [ArtifactID] > 0 AND [Name] LIKE '%'+@workspaceName+'%'",
						Parameters = new[]
						{
							new SqlParameter("@limit", limit),
							new SqlParameter("@workspaceName", queryString)
						}
					}, (record, cancel) => Task.FromResult(record.GetInt32(0))).ConfigureAwait(false);

				foreach (int workspaceID in workspaceIDs)
				{
					// Loop through the results and use the proxy to call another service for more information.
					// Note: async/await and ConfigureAwait(false) is used when making calls external to the service.
					//       See https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/
					//       See also https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.configureawait
					//       See also https://blogs.msdn.microsoft.com/benwilli/2017/02/09/an-alternative-to-configureawaitfalse-everywhere/
					//       See also https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
					//       Warning: Improper use of the tasks can cause deadlocks and performance issues within an application.
					WorkspaceNameModel wsModel = await proxy.GetWorkspaceNameAsync(workspaceID).ConfigureAwait(false);
					if (wsModel != null)
					{
						models.Add(wsModel);
					}
				}
			}
			catch (Exception exception)
			{
				// Note: logging templates should never use interpolation! Doing so will cause memory leaks. 
				_logger.LogWarning(exception, "An exception occured during query for workspace(s) containing {QueryString}.", queryString);

				// Throwing a user defined exception with a 404 status code.
				throw new WorkspaceNameException($"An exception occured during query for workspace(s) containing {queryString}.");
			}

			return models;
		}