Client Manager API

In Relativity, clients are companies or other organizations associated with users and matters. For more information, see Clients on the Relativity Documentation site.

The Services API provides two interfaces for interacting with Client objects. Both interfaces include full support for CRUD and query operations.

  • Relativity.Services.Client.IClientManager in Relativity.Services.Interfaces.dll – asynchronous single-artifact operations with await pattern.
  • kCura.Relativity.Client.Repositories.ClientRepository in kCura.Relativity.Client.dll – synchronous single-artifact and multiple-artifact operations.

Depending on the requirements of you custom solution, you can use both interfaces. You can also interact with the Client objects using the Relativity REST API Client Manager Service.

Complete code samples of operations on the Client objects are included in the APISamples.sln solution in the Relativity SDK.

kCura.Relativity.Client.SamplesLibrary.CS\ServiceHost\ClientManager.cs

For more information, see Relativity SDK samples.

This page contains the following information:

Create clients

The following code sample illustrates how to create a single client asynchronously with the IClientManager interface using the await pattern. Note the use of the ChoiceRef class to set the value of the Status property of the Client object.

public async Task<bool> CreateSingleAsync_Client(IClientManager proxy, IAPILog logger)
{
    bool success = false;
 
    try
    {
        var client = new Relativity.Services.Client.Client();

        client.Name = "My Client";

        client.Number = "123456789";
        
        // Get available status choices
        List<ChoiceRef> choiceRefs = await proxy.GetStatusChoicesForClientAsync();
        ChoiceRef statusRef = choiceRefs.Find(x => x.Name == "Active");
        client.Status = statusRef;

        client.Keywords = "Client Sample";

        client.Notes = "This is the Client for the sample runner";

        // Create the Client
        int artifactID = await proxy.CreateSingleAsync(client);

        if (artifactID != 0)
        {
            success = true;
        }
        else
        {
            logger.LogError("Create failed.");
        }
    }
    catch (ServiceException exception)
    {
        // Exceptions are returned as a ServiceException
        logger.LogError("An error occured: {0}", exception.Message);
    }
 
    return success;
}

Read clients

The following code sample illustrates how to read a single client asynchronously using the IClientManager interface with await pattern.

public async Task<bool> ReadSingleAsync_Client(IClientManager proxy, IAPILog logger, int clientId)
{
    bool success = false;
 
    try
    {
        Relativity.Services.Client.Client client = await proxy.ReadSingleAsync(clientId);

        // Display the search artifact result.
        logger.LogDebug("{0} - {1}. Tenancy Status: {2}", client.ArtifactID, client.Name, client.TenancyStatus);
        success = true;
    }
    catch (ServiceException exception)
    {
        // Exceptions are returned as a ServiceException
        logger.LogError("An error occured: {0}", exception.Message);
    }

   return success;
}

Update clients

The following code sample illustrates how to update a single client asynchronously using the IClientManager interface with await pattern.

public async Task<bool> UpdateSingleAsync_Client(IClientManager proxy, IAPILog logger, int clientId)
{
    bool success = false;

    try
    {
        Client client = await proxy.ReadSingleAsync(clientId);
        client.Name = "My Updated Client";
        List<ChoiceRef> choiceRefs = await proxy.GetStatusChoicesForClientAsync();
        ChoiceRef statusRef = choiceRefs.Find(x => x.Name == "Inactive");
        client.Status = statusRef;

        client.Notes = "New Updated Notes";

        await proxy.UpdateSingleAsync(client);
        success = true;
    }
    catch (ServiceException exception)
    {
        // Exceptions are returned as a ServiceException
        logger.LogError("An error occured: {0}", exception.Message);
    }

    return success;
}

Delete clients

The following code sample illustrates how to delete a single client asynchronously using the IClientManager interface with await pattern.

public static async Task<bool> DeleteSingleAsync_Client(IClientManager proxy, IAPILog logger, int clientId)
{
    bool success = false;
    try
    {
        await proxy.DeleteSingleAsync(clientId);
        logger.LogDebug("Successfully deleted client with ID {0}", clientId);
        success = true;
    }
    catch (ServiceException exception)
    {
        // Exceptions are returned as a ServiceException
        logger.LogError("An error occured: {0}", exception.Message);
    }
    return success;
}

Query clients

The following is an example of an asynchronous query of Client objects through the IClientManager interface. Note the use the QueryAsync() and QuerySubsetAsync() method. The query condition checks if the search name starts with the string "API". If the query returns a token value that is not null, more results are available than initially specified in the length property (5 in this case), and they are subsequently retrieved by using the QuerySubsetAsync() method. When the length parameter is not specified, its value defaults to 0, and the number of returned results defaults to the Instance setting table value of PDVDefaultQueryCacheSize of 10000. For more information about query conditions and using query tokens, see Search Relativity.

public async Task<bool> QueryAsync_Client(IClientManager proxy, IAPILog logger, int clientId)
{
    bool success = false;
    try
    {
        // Create a new instance of a Query.
        var query = new Relativity.Services.Query();

        // Define the search length. This is the number of results to be returned.
        // If more results are available the search results will contain a query token 
        // that can be used with QuerySubsetAsync to get the additional results from 
        // the search query. Setting length to 0 will use the default length defined 
        // in Relativity.
        int length = 5;

        // Define the search condition for the query.  
        // Conditions can be created programmatically using Conditions and converted
        // to a query string using the ToQueryString extension method that the query conditions accepts.
        Relativity.Services.Condition queryCondition = new Relativity.Services.TextCondition(
            ClientFieldNames.Name, 
            TextConditionEnum.StartsWith, 
            "API");
        string queryString = queryCondition.ToQueryString();
        query.Condition = queryString;

        // Create an instance of a Sort and define how this query is to be sorted.
        var sortBy = new Relativity.Services.Sort();
        sortBy.FieldIdentifier.Name = "ArtifactID";
        sortBy.Order = 0;
        sortBy.Direction = SortEnum.Descending;
        query.Sorts.Add(sortBy);

        // Query for search objects given the above query condition and sort order.
        ClientQueryResultSet queryResultSet = await proxy.QueryAsync(query, length);
        if (queryResultSet.Success)
        {
            // Loop through the search results and display successful search results.
            foreach (Relativity.Services.Result<Relativity.Services.Client.Client> result in queryResultSet.Results)
            {
                // If the result was successful display the ArtifactID and Name; if it is not display the error message.
                if (result.Success)
                {
                    logger.LogDebug("{0} - {1}", result.Artifact.ArtifactID, result.Artifact.Name);
                }
                else
                {
                    logger.LogError("Error: {0}", result.Message);
                }
            }

            // If a QueryToken exists more results are available.
            int queryStartPosition = 1 + length;
            while (!string.IsNullOrEmpty(queryResultSet.QueryToken))
            {
                // Query for the subset of query results.
                queryResultSet = await proxy.QuerySubsetAsync(queryResultSet.QueryToken, queryStartPosition, length);

                // Repeat the same process to read results as seen in QueryAsync.
                // Check to see if the query was successful.
                if (queryResultSet.Success)
                {
                    // Loop through the search results and display successful search results.
                    foreach (Relativity.Services.Result<Relativity.Services.Client.Client> result in queryResultSet.Results)
                    {
                        // If the result was successful display the ArtifactID and Name, if it is not display the error message.
                        if (result.Success)
                        {
                            logger.LogDebug("{0} - {1}", result.Artifact.ArtifactID, result.Artifact.Name);
                        }
                        else
                        {
                            logger.LogError("Error: {0}", result.Message);
                        }
                    }

                    // Shift the starting position.
                    queryStartPosition += length;
                }
                else
                {
                    logger.LogError("Error: QuerySubsetAsync was not successful - {0}", queryResultSet.Message);
                }
            }
            success = true;
        }
        else
        {
            logger.LogError("Error: QueryAsync was not successful - {0}", queryResultSet.Message);
        }
    }
    catch (ServiceException exception)
    {
        // Exceptions are returned as an ServiceException
        logger.LogError("An error occured: {0}", exception.Message);
    }

    return success;
}

Get status choices

IClientManager interface provides the GetStatusChoicesForClientAsync() helper method to easily return the choices that can be used in the Status property.

public async Task<bool> GetStatusChoicesForClientAsync_Client(IClientManager proxy)
{
    bool success = false;

    // This method will return all status choices available for clients
    List<ChoiceRef> choices = await proxy.GetStatusChoicesForClientAsync();

    foreach (ChoiceRef choiceRef in choices)
    {
        logger.LogDebug("{0} - {1}", choiceRef.ArtifactID, choiceRef.Name);
    }
 
    return success;
}

For additional code samples of using GetStatusChoicesForClientAsync() , see Create clients and Update clients.

Multi-tenancy

With the introduction of multi-tenancy in Relativity 9, Client has become the parent of the Group, User, and Workspace objects. For general information about Relativity multi-tenancy, see Multi-tenancy in the Relativity Server2021 Documentation site.

Note the following:

  • You cannot use the Services API to make a client a tenant.
  • You can read the Client TenancyStatus property to determine whether a client is a tenant. See the code sample in Read Clients.

For additional information on the impact of multi-tenancy on the Services API objects, see Group, User, and Workspace.