Utiliser des tables élastiques à l’aide de code

Cet article décrit comment utiliser du code pour effectuer des opérations de données sur des tables élastiques.

Utiliser le jeton de session

Comme mentionné dans Niveau de cohérence, vous pouvez obtenir une cohérence au niveau de la session en transmettant le jeton de session en cours avec vos requêtes. Si vous n’incluez pas le jeton de session, les données que vous récupérez peuvent ne pas inclure les modifications de données que vous venez d’effectuer.

Obtenir le jeton de session

Le jeton de session est disponible dans la réponse de toutes les opérations d’écriture. Recherchez la valeur x-ms-session-token.

Pour toute OrganizationResponse qui exécute une opération d’écriture, vous pouvez saisir la valeur x-ms-session-token dans la collection des Résultats.

Notes

DeleteResponse ne renvoie pas actuellement la valeur x-ms-session-token. Plus d’informations, consultez Problèmes connus : la valeur x-ms-session-token n’est pas renvoyée pour les opérations de suppression.

string sessionToken = response.Results["x-ms-session-token"].ToString();

Envoi du jeton de session

La manière dont vous envoyez le jeton de session lors d’une opération de lecture varie selon que vous utilisez le kit de développement logiciel (SDK) ou l’API web.

Lorsque vous effectuez une opération qui récupère des données, définissez le paramètre facultatif SessionToken sur OrganizationRequest.

var request = new RetrieveRequest
{
    Target = new EntityReference("contoso_sensordata", sensordataid),
    ColumnSet = new ColumnSet("contoso_value"),
    ["partitionId"] = deviceId,
    ["SessionToken"] = sessionToken
};

En savoir plus sur l’utilisation des paramètres facultatifs.

Spécifier le PartitionId

Comme mentionné dans Partitionnement et mise à l’échelle horizontale, chaque table élastique a une colonne partitionid que vous devez utiliser si vous choisissez d’appliquer une stratégie de partitionnement pour la table. Sinon, ne définissez pas de valeur pour la colonne partitionid.

Après avoir spécifié une valeur non nulle pour la colonne partitionid lors de la création d’une ligne, vous devez la spécifier lorsque vous effectuez toute autre opération de données sur cette ligne. Vous ne pouvez pas modifier la valeur ultérieurement.

Si vous ne définissez pas de valeur partitionid pour un enregistrement lors de sa création, la valeur de la colonne partitionid reste nulle et vous ne pouvez pas la modifier ultérieurement. Dans ce cas, vous pouvez identifier les enregistrements à l’aide de la clé primaire comme vous le faites normalement avec les tables standard. Il n’est pas nécessaire de préciser une valeur partitionid.

Notes

Les exemples de cet article supposent que vous spécifiez une valeur non nulle pour la colonne partitionid.

Vous pouvez définir la valeur partitionid des manières suivantes lorsque vous exécutez diverses opérations de données.

Utiliser la clé secondaire

Comme mentionné dans Clés secondaires, chaque table élastique a une clé secondaire nommée KeyForNoSqlEntityWithPKPartitionId. Cette clé secondaire combine la clé primaire de la table avec la colonne partitionid.

Vous pouvez utiliser cette clé secondaire pour spécifier la valeur partitionid lorsque vous utilisez les opérations Retrieve, Update ou Delete.

Cet exemple montre comment vous pouvez utiliser la clé secondaire pour spécifier la valeur partitionid lorsque vous utilisez des requêtes Retrieve, Update et Delete sur des tables élastiques.

var keys = new KeyAttributeCollection() {
    { "contoso_sensordataid", sensordataid },
    { "partitionid", deviceId }
};

var entity = new Entity("contoso_sensordata", keys)

Utilisation du paramètre partitionId

Actuellement, vous pouvez utiliser un paramètre partitionId pour spécifier la valeur de la colonne partitionid uniquement pour les opérations Retrieve et Delete. Plus d’informations, voir Problème connu : le paramètre facultatif partitionId n’est pas disponible pour tous les messages.

Notes

Le paramètre partitionId ne fonctionne pas avec les messages Create, Update ou Upsert , et il est ignoré s’il est envoyé.

request["partitionId"] = "device-001"

Utilisation directe de la colonne partitionid

Pour les opérations Create, Upsert ou Update , vous pouvez spécifier directement la valeur de la colonne partitionid.

Cet exemple montre comment vous pouvez spécifier directement la colonne partitionid dans Entity lorsque vous exécutez une opération Create, Upsert ou Update.

var entity = new Entity("contoso_sensordata", sensordataid)
{
    Attributes = {
        { "partitionid", "device-001" }
    }
};

Créer un enregistrement dans une table élastique

Cet exemple crée une ligne dans la table contoso_SensorData avec partitionid défini sur deviceid. Il définit également la colonne ttlinseconds pour garantir que la ligne expire après un jour (86 400 secondes) et est automatiquement supprimée de Dataverse.

Cet exemple capture également la valeur de x-ms-session-token que vous pouvez utiliser lorsque vous récupérez l’enregistrement créé.

/// <summary>
/// Demonstrates creating a record with a partitionid and capturing the session token
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
/// <param name="deviceId">The value used as partitionid for the contoso_sensordata table. </param>
/// <param name="sessionToken">The current session token</param>
/// <returns>The Id of the created record.</returns>
public static Guid CreateExample(
    IOrganizationService service, 
    string deviceId, 
    ref string sessionToken )
{
    var entity = new Entity("contoso_sensordata")
    {
        Attributes =
            {
                { "contoso_deviceid", deviceId },
                { "contoso_sensortype", "Humidity" },
                { "contoso_value", 40 },
                { "contoso_timestamp", DateTime.UtcNow},
                { "partitionid", deviceId },
                { "ttlinseconds", 86400  }  // 86400  seconds in a day
            }
    };

    var request = new CreateRequest { 
        Target = entity
    };

    var response = (CreateResponse)service.Execute(request);

    // Capture the session token
    sessionToken = response.Results["x-ms-session-token"].ToString();

    return response.id;
}

Utilisez la valeur x-ms-session-token renvoyée pour définir le paramètre facultatif SessionToken lorsque vous récupérez l’enregistrement que vous avez créé. En savoir plus sur l’envoi du jeton de session.

Notes

Insertion profonde n’est pas prise en charge avec les tables élastiques. Chaque enregistrement associé doit être créé indépendamment. Seules les tables standard prennent en charge l’insertion profonde

Définition de la valeur de la clé primaire

Si vous ne spécifiez pas de valeur de clé primaire, Dataverse définit une valeur de clé primaire pour l’enregistrement lorsque vous le créez. Laisser Dataverse définir cette valeur est la pratique courante. Vous pouvez spécifier la valeur de la clé primaire si nécessaire. Pour les tables élastiques, il n’y a aucun avantage en termes de performances à laisser Dataverse définir la valeur de la clé primaire.

Les tables élastiques ne renvoient pas d’erreur lorsque vous créez un enregistrement avec une valeur de clé primaire qui n’est pas unique. En définissant les valeurs de clé primaire avec des tables élastiques, vous pouvez créer des enregistrements ayant les mêmes valeurs de clé primaire et des valeurs partitionid différentes. Cependant, ce modèle n’est pas compatible avec Power Apps. Ne créez pas d’enregistrements avec des valeurs de clé primaire en double lorsque les utilisateurs ont besoin d’utiliser ces données dans des applications canevas ou pilotées par modèle.

Mettre à jour un enregistrement dans une table élastique

Cet exemple met à jour les valeurs contoso_value et contoso_timestamp d’une ligne existante dans la table contoso_SensorData à l’aide de la clé primaire contoso_sensordataid et partitionid = 'device-001'.

Si vous utilisez une stratégie de partitionnement, la clé primaire et les colonnes partitionid doivent identifier de manière unique une ligne de table élastique existante. La valeur partitionid d’une ligne existante ne peut pas être mise à jour et n’est utilisé que pour identifier de manière unique la ligne à mettre à jour.

Cet exemple utilise la clé secondaire KeyForNoSqlEntityWithPKPartitionId pour identifier de manière unique l’enregistrement en utilisant à la fois la clé primaire et les valeurs partitionid. En savoir plus sur les clés secondaires.

Cet exemple montre comment utiliser la valeur partitionid comme clé secondaire.

/// <summary>
/// Demonstrates updating elastic table row with partitionid as alternate key.
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
/// <param name="sensordataid">The unique identifier of the contoso_sensordata table.</param>
/// <param name="deviceId">The value used as partitionid for the contoso_sensordata table. </param>
/// <param name="sessionToken">The current session token</param>
public static void UpdateExample(
    IOrganizationService service, 
    Guid sensordataid, 
    string deviceId, 
    ref string sessionToken)
{
    var keys = new KeyAttributeCollection() {
        { "contoso_sensordataid", sensordataid },
        { "partitionid", deviceId }
    };

    var entity = new Entity("contoso_sensordata", keys)
    {
        Attributes = {
            { "contoso_value", 60 },
            { "contoso_timestamp", DateTime.UtcNow }
        }
    };

    var request = new UpdateRequest { 
        Target = entity,
        ["SessionToken"] = sessionToken
    };

    var response = (UpdateResponse)service.Execute(request);

    // Capture the session token
    sessionToken = response.Results["x-ms-session-token"].ToString();
}

En savoir plus sur l’utilisation de la classe Entity pour définir des clés secondaires.

Récupérer un enregistrement dans une table élastique

Si la valeur partitionid a été définie lors de la création d’un enregistrement de la table élastique, vous devez l’utiliser avec la valeur de la clé primaire pour identifier de manière unique un enregistrement.

Si le partitionid n’a pas été défini, vous pouvez récupérer l’enregistrement de la manière habituelle, en utilisant uniquement la valeur de la clé primaire.

Il existe deux manières différentes de composer une requête pour récupérer un enregistrement en utilisant la valeur partitionid.

Cet exemple utilise la classe RetrieveRequest. La propriété Target définie sur une EntityReference créée à l’aide du constructeur qui accepte une KeyAttributeCollection pour utiliser la clé secondaire KeyForNoSqlEntityWithPKPartitionId. En savoir plus sur l’utilisation de la classe EntityReference avec des clés secondaires.

public static void RetrieveExampleAlternateKey(IOrganizationService service, Guid sensorDataId, string deviceId) {

    var keys = new KeyAttributeCollection() {
        { "contoso_sensordataid", sensorDataId },
        { "partitionid", deviceId }
    };

    var entityReference = new EntityReference("contoso_sensordata", keys);

    var request = new RetrieveRequest { 
        ColumnSet = new ColumnSet("contoso_value"),
        Target = entityReference
    };

    var response = (RetrieveResponse)service.Execute(request);

    Console.WriteLine($"contoso_value: {response.Entity.GetAttributeValue<int>("contoso_value")}");
}

Cet exemple utilise un paramètre facultatif nommé partitionId sur la classe RetrieveRequest. En savoir plus sur l’utilisation des paramètres facultatifs.

public static void RetrieveExampleOptionalParameter(IOrganizationService service, Guid sensorDataId, string deviceId)
{
    var entityReference = new EntityReference("contoso_sensordata", sensorDataId);

    var request = new RetrieveRequest
    {
        ColumnSet = new ColumnSet("contoso_value"),
        Target = entityReference,
        ["partitionId"] = deviceId
    };

    var response = (RetrieveResponse)service.Execute(request);

    Console.WriteLine($"contoso_value: {response.Entity.GetAttributeValue<int>("contoso_value")}");
}

Interroger les lignes d’une table élastique

Lorsque vous interrogez les lignes d’une table élastique, vous obtenez de meilleures performances si vous limitez votre requête à une partition spécifique. Sinon, votre requête renvoie des données sur toutes les partitions logiques, ce qui n’est pas aussi rapide.

Notes

Lorsque vous utilisez cette approche, le paramètre doit utiliser le nom partitionId (avec une majuscule I) au lieu de partitionid (dans toutes les lettres minuscules).

Lorsque vous spécifiez un filtre de cette façon, vous n’avez pas besoin de spécifier les critères de filtre sur partitionid dans votre requête de la manière normale (c’est-à-dire, en utilisant FetchXML condition, QueryExpression ConditionExpression ou l’API web $filter).

Spécifier un filtre sur la valeur partitionid de la manière habituelle n’a pas les mêmes avantages en termes de performances que de le spécifier via le paramètre partitionId comme indiqué dans les exemples suivants.

Ces exemples récupèrent les 5 000 premières lignes de la table contoso_SensorData qui appartient à la partition logique où partitionid = 'deviceid-001'.

public static EntityCollection RetrieveMultipleExample(IOrganizationService service)
{
    var request = new RetrieveMultipleRequest
    {
        Query = new QueryExpression("contoso_sensordata")
        {
            ColumnSet = new ColumnSet("contoso_value")
        },
        ["partitionId"] = "deviceid-001"
    };

    var response = (RetrieveMultipleResponse)service.Execute(request);
    return response.EntityCollection;
}

Actuellement, les tables élastiques ne prennent pas en charge le renvoi des lignes associées lors de l’exécution d’une requête. Si vous essayez de renvoyer des lignes associées, Dataverse génère une erreur avec le code 0x80048d0b et le message suivant :

Link entities are not supported.

Cependant, les tables élastiques prennent en charge le renvoi des lignes associées lors de la récupération d’une seule ligne.

Faire un upsert d’un enregistrement dans une table élastique

Important

Les opérations d’upsert avec des tables élastiques diffèrent des opérations d’upsert avec des tables standard. Les opérations d’upsert sont censées contenir la charge utile complète et remplacent toutes les données d’enregistrement existantes. Ils n’appellent pas les messages Create ou Update. En savoir plus sur l’upsert de table élastique.

Avec les tables élastiques, si un enregistrement ayant un ID donné et partitionid n’existe pas, il est créé. S’il existe déjà, il est remplacé.

Cet exemple insère une ligne dans la table contoso_SensorData avec la valeur id spécifiée et partitionid = deviceid-001.

/// <summary>
/// Demonstrates an upsert operation
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
/// <param name="id">The id of the record to update or create.</param>
/// <param name="sessionToken">The current session token</param>
/// <returns>Whether a record was created or not</returns>
public static bool UpsertExample(IOrganizationService service, Guid id, ref string sessionToken)
{
    var entity = new Entity("contoso_sensordata", id)
    {
        Attributes = {
            { "contoso_deviceid", "deviceid-001" },
            { "contoso_sensortype", "Humidity" },
            { "contoso_value", 60 },
            { "contoso_timestamp", DateTime.UtcNow },
            { "partitionid", "deviceid-001" },
            { "ttlinseconds", 86400 }
        }
    };

    var request = new UpsertRequest
    {
        Target = entity,
        ["SessionToken"] = sessionToken
    };

    var response = (UpsertResponse)service.Execute(request);

    // Capture the session token
    sessionToken = response.Results["x-ms-session-token"].ToString();

    return response.RecordCreated;
}

Supprimer un upsert d’un enregistrement dans une table élastique

Lorsque vous supprimez un enregistrement qui utilise une valeur partitionid personnalisée, vous devez inclure la valeur partitionid.

Cet exemple supprime une ligne dans la table contoso_SensorData avec l’ID spécifié et partitionid = 'deviceid-001'.

/// <summary>
/// Demonstrates a delete operation
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
/// <param name="sensordataid">The unique identifier of the contoso_sensordata table.</param>
/// <param name="sessionToken">The current session token</param>
public static void DeleteExample(
    IOrganizationService service, 
    Guid sensordataid, 
    ref string sessionToken)
{
    var request = new DeleteRequest
    {
        Target = new EntityReference("contoso_sensordata", sensordataid),
        ["partitionId"] = "deviceid-001"
    };

    var response = service.Execute(request);
    // Known issue: Value not currently being returned.
    // sessionToken = response.Results["x-ms-session-token"].ToString();
}

Opérations en masse avec des tables élastiques

Souvent, les applications doivent ingérer une grande quantité de données dans Dataverse en peu de temps. Dataverse contient un groupe de messages conçus pour atteindre un débit élevé. Avec les tables élastiques, le débit peut être encore plus élevé.

Les opérations en bloc sont optimisées pour les performances lors de l’exécution de plusieurs opérations d’écriture sur la même table en prenant un lot de lignes comme entrée dans une seule opération d’écriture. En savoir plus sur les messages d’opération en bloc (version préliminaire).

Utiliser CreateMultiple avec des tables élastiques

Vous pouvez utiliser le message CreateMultiple avec le SDK pour .NET ou l’API Web.

Cet exemple utilise la classe CreateMultipleRequest pour créer plusieurs lignes dans la table élastique contoso_SensorData.

public static Guid CreateMultiple(IOrganizationService service)
{
    string tableLogicalName = "contoso_sensordata";

    List<Microsoft.Xrm.Sdk.Entity> entityList = new List<Microsoft.Xrm.Sdk.Entity>
    {      
        new Microsoft.Xrm.Sdk.Entity(tableLogicalName)
        {
            Attributes =
            {
                { "contoso_deviceId", "deviceid-001" },
                { "contoso_sensortype", "Humidity" },
                { "contoso_value", "40" },
                { "contoso_timestamp", "2023-05-01Z05:00:00"},
                { "partitionid", "deviceid-001" },
                { "ttlinseconds", 86400 }
            }
        },
        new Microsoft.Xrm.Sdk.Entity(tableLogicalName)
        {
            Attributes =
            {
                { "contoso_deviceId", "deviceid-002" },
                { "contoso_sensortype", "Humidity" },
                { "contoso_value", "10" },
                { "contoso_timestamp", "2023-05-01Z09:30:00"},
                { "partitionid", "deviceid-002" },
                { "ttlinseconds", 86400 }
            }
        }
        new Microsoft.Xrm.Sdk.Entity(tableLogicalName)
        {
            Attributes =
            {
                { "contoso_deviceId", "deviceid-002" },
                { "contoso_sensortype", "Pressure" },
                { "contoso_value", "20" },
                { "contoso_timestamp", "2023-05-01Z07:20:00"},
                { "partitionid", "deviceid-002" },
                { "ttlinseconds", 86400 }
            }
        }
    };

    // Create an EntityCollection populated with the list of entities.
    EntityCollection entities = new(entityList)
    {
        EntityName = tableLogicalName
    };

    // Use CreateMultipleRequest
    CreateMultipleRequest createMultipleRequest = new()
    {
        Targets = entities,
    };
    return service.Execute(request);
}

Utiliser UpdateMultiple avec des tables élastiques

Vous pouvez utiliser le message UpdateMultiple avec le SDK pour .NET ou l’API Web.

Cet exemple utilise la classe UpdateMultipleRequest pour mettre à jour plusieurs lignes de la table élastique contoso_SensorData. Ces mises à jour définissent la colonne contoso_value.

public static Guid UpdateMultiple(IOrganizationService service)
{
    string tableLogicalName = "contoso_sensordata";

    List<Microsoft.Xrm.Sdk.Entity> entityList = new List<Microsoft.Xrm.Sdk.Entity>
    {
        new Microsoft.Xrm.Sdk.Entity(tableLogicalName)
        {
            Attributes =
            {
                { "contoso_value", "45" },
                { "partitionid", "deviceid-001" }
            }
        },
        new Microsoft.Xrm.Sdk.Entity(tableLogicalName)
        {
            Attributes =
            {
                { "contoso_value", "15" },
                { "partitionid", "deviceid-002" }
            }
        }
        new Microsoft.Xrm.Sdk.Entity(tableLogicalName)
        {
            Attributes =
            {
                { "contoso_value", "25" },
                { "partitionid", "deviceid-002" }
            }
        }
    };

    // Create an EntityCollection populated with the list of entities.
    EntityCollection entities = new(entityList)
    {
        EntityName = tableLogicalName
    };

    // Use UpdateMultipleRequest
    UpdateMultipleRequest updateMultipleRequest = new()
    {
        Targets = entities,
    };
    return service.Execute(request);
}

Utiliser DeleteMultiple avec des tables élastiques

Vous pouvez utiliser le message DeleteMultiple avec le SDK pour .NET ou l’API Web.

Notes

Avec le kit de développement logiciel (SDK), vous devez utiliser la classe OrganizationRequest car le SDK n’a pas actuellement de classe DeleteMultipleRequest. En savoir plus sur l’utilisation des messages avec le SDK pour .NET.

La méthode statique DeleteMultipleExample suivante utilise le message DeleteMultiple avec la classe OrganizationRequest pour supprimer plusieurs lignes de la table élastique. contoso_SensorData. La clé secondaire est utilisé pour inclure la valeur partitionid pour identifier de manière unique les lignes.

public static void DeleteMultipleExample(IOrganizationService service)
{
    string tableLogicalName = "contoso_sensordata";

    List<EntityReference> entityReferences = new() {
        {
            new EntityReference(logicalName: tableLogicalName,
                keyAttributeCollection: new KeyAttributeCollection
                {
                    { "contoso_sensordataid", "3f56361a-b210-4a74-8708-3c664038fa41" },
                    { "partitionid", "deviceid-001" }
                })
        },
        { new EntityReference(logicalName: tableLogicalName,
            keyAttributeCollection: new KeyAttributeCollection
            {
                { "contoso_sensordataid", "e682715b-1bba-415e-b2bc-de9327308423" },
                { "partitionid", "deviceid-002" }
            })
        }
    };

    OrganizationRequest request = new(requestName:"DeleteMultiple")
    {
        Parameters = {
            {"Targets", new EntityReferenceCollection(entityReferences)}
        }
    };

    service.Execute(request);
}

Étapes suivantes

Découvrez comment utiliser du code pour créer et interroger des données JSON (JavaScript Object Notation) dans les colonnes JSON des tables élastiques.

Voir aussi

Tables élastiques pour les développeurs
Créer des tables élastiques à l’aide de code
Interroger les colonnes JSON dans les tables élastiques
Exemple de code de table élastique
Messages d’opération en bloc (version préliminaire)