次の方法で共有


一括操作メッセージを使う

Microsoft Dataverse テーブルの複数の行で操作を実行するときに最適なパフォーマンスを得るには、次のいずれかの一括操作メッセージを使用します。

  • CreateMultiple: 1 つのリクエストで同じタイプの複数のレコードを作成します。
  • UpdateMultiple: 1 つのリクエストで同じタイプの複数のレコードを更新します。
  • UpsertMultiple: 1 つのリクエストで同じタイプの複数のレコードを作成して更新します。
  • DeleteMultiple: エラスティック テーブルのみ。 1 つのリクエストで同じタイプの複数のレコードを削除します。

ヒント

ExecuteMultipleなどのバッチ API と比較してこれらの API を使用するタイミングなど、一括操作を実行する場合のオプションに関するガイダンスについては、「一括操作のパフォーマンスを最適化する」を参照してください。

使用例

次のサンプル コードは、一括操作メッセージの使用方法を示しています。 サンプルをここからダウンロードできます github.com/microsoft/PowerApps-Samples:

CreateMultiple

1 つのリクエストで同じタイプの複数のレコードを作成します。

CreateMultipleRequest クラスを使用します。

/// <summary>
/// Demonstrates the use of the CreateMultiple Message
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance.</param>
/// <param name="recordsToCreate">A list of records of the same table to create.</param>
/// <returns>The Guid values of the records created.</returns>
static Guid[] CreateMultipleExample(IOrganizationService service,
    List<Entity> recordsToCreate)
{

    // Create an EntityCollection populated with the list of entities.
    EntityCollection entities = new(recordsToCreate)
    {
        // All the records must be for the same table.
        EntityName = recordsToCreate[0].LogicalName
    };

    // Instantiate CreateMultipleRequest
    CreateMultipleRequest createMultipleRequest = new()
    {
        Targets = entities,
    };

    // Send the request
    CreateMultipleResponse createMultipleResponse =
                (CreateMultipleResponse)service.Execute(createMultipleRequest);

    // Return the Ids of the records created.
    return createMultipleResponse.Ids;
}

UpdateMultiple

1 つのリクエストで同じタイプの複数のレコードを更新します。

個々のレコードを更新する場合と同様に、 UpdateMultiple を使用して送信するデータには、変更する値のみが含まれている必要があります。 詳細については、 SDK for .NET でレコードを更新 する方法と、 Web API を使用してレコードを更新する方法に関するページを参照してください。

UpdateMultipleRequest クラスを使用します。

/// <summary>
/// Demonstrates the use of the UpdateMultiple message.
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance.</param>
/// <param name="recordsToUpdate">A list of records to create.</param>
static void UpdateMultipleExample(IOrganizationService service, List<Entity> recordsToUpdate) {
    // Create an EntityCollection populated with the list of entities.
    EntityCollection entities = new(recordsToUpdate)
    {
        // All the records must be for the same table.
        EntityName = recordsToUpdate[0].LogicalName
    };

    // Use UpdateMultipleRequest
    UpdateMultipleRequest updateMultipleRequest = new()
    {
        Targets = entities,
    };

    service.Execute(updateMultipleRequest);
}

UpdateMultiple Targets パラメータの重複レコード

UpdateMultiple は、ペイロード内の同じ主キーまたは代替キー値を持つ複数のレコードをサポートしていません。 複数のレコードがある場合、Targets パラメータがプライマリまたは代替キーによって一意に識別される場合、操作は最初のレコードに対してのみ実行されます。 この操作では、ペイロード内の同じキー値を持つ後続のレコードはすべて無視されます。 この動向は UpsertMultiple とは異なります

UpsertMultiple (複数のデータを追加・更新)

テーブルが Dataverse に存在するかどうかがわからない場合は、 Upsert を使用して外部ソースとデータを統合します。 Upsert 操作はレコードを識別する際に、代替キーに依存します。 UpsertMultiple を使用して Upsert 操作を一括で実行します。

UpsertMultipleRequest クラスを使用します。

この静的 UpsertMultipleExample メソッドは、代替キーとして構成された samples_bankaccount という名前の文字列の列を持つ、samples_accountname テーブルに依存します。 これには、samples_description という名前の文字列の列もあります。 このコードは代替キー値の指定に keyName と keyValue を設定するエンティティ コンストラクター を使用します。

/// <summary>
/// Demonstrates using UpsertMultiple with alternate key values
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance</param>
static void UpsertMultipleExample(IOrganizationService service)
{
    var tableLogicalName = "samples_bankaccount";
    // samples_accountname string column is configued as an alternate key
    // for the samples_bankaccount table
    var altKeyColumnLogicalName = "samples_accountname";

    // Create one record to update with upsert
    service.Create(new Entity(tableLogicalName)
    {
        Attributes =
        {
            {altKeyColumnLogicalName, "Record For Update"},
            {"samples_description","A record to update using Upsert" }
        }
    });

    // Using the Entity constructor to specify alternate key
    Entity toUpdate = new(
            entityName: tableLogicalName,
            keyName: altKeyColumnLogicalName,
            // Same alternate key value as created record.
            keyValue: "Record For Update");
    toUpdate["samples_description"] = "Updated using Upsert";

    Entity toCreate = new(
        entityName: tableLogicalName,
        keyName: altKeyColumnLogicalName,
        keyValue: "Record For Create");
    toCreate["samples_description"] = "A record to create using Upsert";

    // Add the records to a collection
    EntityCollection records = new()
    {
        EntityName = tableLogicalName,
        Entities = { toUpdate, toCreate }
    };

    // Send the request
    UpsertMultipleRequest request = new()
    {
        Targets = records
    };

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

    // Process the responses:
    foreach (UpsertResponse item in response.Results)
    {
        Console.WriteLine($"Record {(item.RecordCreated ? "Created" : "Updated")}");
    }
}

出力:

Record Updated
Record Created

この例でレコードが作成されるか更新されるかは、sample_keyattribute の値が一致するレコードが存在するかどうかによって決まります。 データ レコードが作成されたか更新されたかを示す情報は返されません。

SDK の例

「Sample: SDK for .NET 一括操作を使用」の中で"UpsertMultiple" プロジェクトを探します

可用性

UpsertMultipleCreateMultipleUpdateMultiple に対応したテーブルで使用できます。 このサポートには、すべてのエラスティック テーブルが含まれます。 標準テーブルを使用 した可用性 で見つかったクエリは、 UpsertMultipleの結果を返しませんが、テーブルが CreateMultipleUpdateMultipleの両方をサポートしているかどうかを検出するために使用できます。

これらのクエリは、 UpsertMultiple メッセージの結果を返しません。 CreateMultipleUpdateMultipleの両方をサポートするテーブルは、UpsertMultipleをサポートします。

UpsertMultiple Targets パラメータの重複レコード

UpsertMultiple は、ペイロード内の同じ主キーまたは代替キー値を持つ複数のレコードをサポートしていません。 Targets パラメーター内の複数のレコードが主キーまたは代替キーによって一意に識別された場合、UpsertMultipleはエラーを返します。 この動向は UpdateMultiple とは異なります

複数削除

1 回のリクエストでエラスティック テーブル内の複数行のデータを削除します。

SDK for .NET には クラスがないため、DeleteMultipleRequest クラスを使用します。 詳細については、「 SDK for .NET でメッセージを使用する」を参照してください。

次のDeleteMultipleExample静的メソッドでは、DeleteMultiple メッセージを使用し、代替キーを使用して行を一意に識別するcontoso_SensorDataを含めることで、partitionidエラスティック テーブルから複数の行を削除します。

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);
}

DeleteMultiple の可用性

DeleteMultiple は、エラスティック テーブルに対してのみサポートされます。 エラスティック テーブルはテーブル リレーションシップのカスケード動作をサポートしないため、削除操作の実行時間が予測不能になる可能性があります。 標準テーブルで DeleteMultiple を使用すると、次のエラーが発生します: DeleteMultiple has not yet been implemented.

DeleteMultiple の使用例

GitHub github.com/microsoft/PowerApps-Samples にサンプル コードが用意されています。

標準テーブルとエラスティック テーブルの使用法

標準テーブルとエラスティック テーブルの両方で、一括操作メッセージを使用するとパフォーマンスが大幅に向上しますが、異なる方法で使用する必要があります。 次の表では、違いについて要約します。

違い Standard エラスティック
レコードの数 レコード数が多いほど、操作は効率的になります。 レコードの数に制限はありませんが、メッセージのサイズと時間には制限があります。 一度に 100 ~ 1,000 レコードを送信します。 一度に 100 件のレコードを送信します。
エラー時の動作 エラーが発生すると、すべての操作がロールバックされます。 部分的に成功する可能性はあります。
可用性 すべての標準テーブルがこれらのメッセージをサポートしているわけではありません。 メッセージはすべてのエラスティック テーブルで利用可能です。
複数削除 使用不可。 代わりに、SDK BulkDeleteRequest クラス または Web API BulkDelete アクション を使用します。 データを一括削除する方法をご覧ください。 SDK の DeleteMultipleRequest クラス または Web API の DeleteMultiple アクションを使用してください

標準テーブルとエラスティック テーブルの使用方法は異なりますが、これは標準テーブルが Azure SQL を使用し、トランザクションをサポートしているためです。 エラスティック テーブルでは Azure Cosmos DB が使用されます。これはトランザクションをサポートしていませんが、低待機時間で高いレベルのスループットで大量のデータを処理します。 以下のセクションで詳細情報を説明します。 エラスティック テーブルでの一括操作の詳細をご覧ください。

レコードの数

各リクエストに含める必要があるレコードの数は、標準テーブルを使用しているか、エラスティック テーブルを使用しているかによって異なります。

ヒント

一括操作メッセージを並行して送信すると、標準テーブルとエラスティック テーブルの両方でスループットが向上します。

標準テーブルのレコード件数

標準テーブルでの一括操作は、単一トランザクションで複数の行に対して実行するように最適化されています。 リクエストあたりの操作数が増加すると、操作がより効率的になり、全体的なパフォーマンスが向上します。 この最適化により、一括操作用に登録されているプラグインステップも効率的になります。 1 回の操作に対してプラグインが呼び出されるたびに、プロセスでロジックを含むプラグイン クラスを呼び出すには、数ミリ秒が必要です。 一括操作メッセージのプラグインを登録すると、クラスが 1 回呼び出され、すべての操作をより効率的に処理できます。 CreateMultiple および UpdateMultiple (プレビュー) のプラグインを記述する方法について説明します

このパフォーマンス上の利点により、各要求で使用できるレコードの最大数を送信することが推奨されます。 ただし、レコードの数が増えると、リクエストのサイズも大きくなり、リクエストの処理に時間がかかるようになります。 最終的に、 メッセージのサイズと時間制限が発生します。 これらの制限に達すると、操作全体が失敗します。 送信できるレコード数に制限はありません。 最適な数を見つけるには、実験が必要になる場合があります。 一般に、レコード データのサイズが小さく、プラグインがない場合は、要求あたり 100 から 1,000 個のレコードを開始するのが妥当な場所です。通常、発生する可能性があるエラーの種類は、各要求で送信するレコードを減らすことによって対処できます。 送信するエンティティの数を構成して、送信数を減らして適応できるようにする機能を含めます。

エラスティック テーブルのレコード件数

エラスティック テーブルにはトランザクションがないため、リクエストごとにレコードの最大数を送信しようとしてもパフォーマンス上の利点はありません。 最大スループットを実現するために、要求ごとに 100 の操作を送信し、要求を並列で送信します。

エラー時の動作

エラーが発生したときの動作は、標準テーブルとエラスティック テーブルのどちらを使用しているかによって異なります。

標準テーブルにおけるエラーの挙動

標準テーブルを使用した一括操作でエラーが発生すると、操作全体がロールバックされます。 標準テーブルで一括操作を使用するのは、すべての操作が成功する可能性が高い場合のみです。 一括操作が失敗した場合に一連の操作をロールバックできるようにするには、SDK ExecuteMultipleRequest クラス または Web API $batchの使用を検討してください。 最初の試行の成功率が低い場合、この戦略ではパフォーマンスが低下します。 このフォールバック戦略は、ほとんどの操作が成功すると予想される場合にのみ使用してください。

エラスティック テーブルでのエラー動作時

エラスティック テーブルでは、一括操作が部分的に成功する可能性があります。 エラーの詳細を使用して、失敗したレコードを特定できます。

SDK でエラスティック テーブルで一括操作を実行すると、障害が発生した場合に OrganizationServiceFault タイプの FaultException がスローされます。 次のコードを使用して、各レコードのステータスを取得できます。

if (ex.Detail.ErrorDetails.TryGetValue("Plugin.BulkApiErrorDetails", out object errorDetails))
{
    List<BulkApiErrorDetail> bulkApiErrorDetails = JsonConvert.DeserializeObject<List<BulkApiErrorDetail>>(errorDetails.ToString());
}

public class BulkApiErrorDetail
{
    public int RequestIndex { get; set; }
    public string Id { get; set; }
    public int StatusCode { get; set; }
}

可用性

一括操作メッセージを利用できるかどうかは、標準テーブルとエラスティック テーブルのどちらを使用しているかによって異なります。 すべてのエラスティック テーブルは CreateMultipleUpdateMultipleUpsertMultiple、および DeleteMultiple メッセージをサポートしています。

標準テーブルでの可用性

CreateMultiple および UpdateMultiple 一括操作メッセージは、カスタム標準テーブルや多くの共通標準テーブルに対して使用できますが、すべてではありません。 個々の標準テーブルでこれらのメッセージがサポートされているかどうかをテストします。 次の例は、テストする方法を示しています。

この静的メソッドを使用して、特定のテーブルが CreateMultiple または UpdateMultiple をサポートしているかどうかを検出します。

/// <summary>
/// Detect whether a specified message is supported for the specified table.
/// </summary>
/// <param name="service">The IOrganizationService instance.</param>
/// <param name="entityLogicalName">The logical name of the table.</param>
/// <param name="messageName">The name of the message.</param>
/// <returns></returns>
public static bool IsMessageAvailable(
    IOrganizationService service,
    string entityLogicalName,
    string messageName)
{
    QueryExpression query = new("sdkmessagefilter")
    {
        ColumnSet = new ColumnSet("sdkmessagefilterid"),
        Criteria = new FilterExpression(LogicalOperator.And)
        {
            Conditions = {
            new ConditionExpression(
                attributeName:"primaryobjecttypecode",
                conditionOperator: ConditionOperator.Equal,
                value: entityLogicalName)
            }
        },
        LinkEntities = {
            new LinkEntity(
                linkFromEntityName:"sdkmessagefilter",
                linkToEntityName:"sdkmessage",
                linkFromAttributeName:"sdkmessageid",
                linkToAttributeName:"sdkmessageid",
                joinOperator: JoinOperator.Inner)
            {
                    LinkCriteria = new FilterExpression(LogicalOperator.And){
                    Conditions = {
                        new ConditionExpression(
                            attributeName:"name",
                            conditionOperator: ConditionOperator.Equal,
                            value: messageName)
                        }
                    }
            }
        }
    };

    EntityCollection entityCollection = service.RetrieveMultiple(query);

    return entityCollection.Entities.Count.Equals(1);
}

メッセージ パイプラインの統合

各一括操作メッセージには、個々の行 ( CreateUpdateDelete) を操作する対応するメッセージがあります。 これらのメッセージは長い間存在しており、多くの組織がこれらのメッセージの使用時に発生するイベントに応じてロジックをカスタマイズしています。

一括操作メッセージの主な要件は、組織が 2 か所でカスタム ロジックを維持してはいけないということです。 同じカスタム ロジックを持ち、それを 1 か所に保持するために、Dataverse はこれらのメッセージのメッセージ処理パイプラインを マージ します。 このマージとはどういう意味ですか?

  • 一括操作メッセージを使用すると、Create パラメーターの各 Update インスタンスに対して、それぞれのイベントとTargets イベントが発生します。 対応する個々のイベントの任意プラグインまたはその他のイベント ハンドラーは、これまでと同様に引き続き機能します。 これらのメッセージによって発生するイベントを管理するために新しいプラグインを作成する必要はありません。

  • 1 つの操作メッセージを使用すると、 パラメーターで渡された単一Entity インスタンスを含む Targets で、それぞれの一括操作イベントが発生します。 現在単一操作イベントに応答しているロジックをより効率的な一括操作イベントに移動でき、そのロジックは個々の操作と複数操作の両方に適用されます。

一括操作メッセージが導入される前は、すべてのカスタム ロジックは単一の操作メッセージ上にありました。 クライアント アプリケーションが一括操作メッセージを使用する場合、そのロジックは引き続き適用されます。 大量の一括操作で使用されるテーブルの場合は、同期ロジックを 1 つのメッセージ イベントから一括操作イベントに移動します。 新しいロジックを導入する場合は、単一操作イベントではなく一括操作イベントを使用してください。

注意

この設計では、重複ロジックがイベントの単一バージョンと複数バージョンの両方に適用される可能性があります。 Dataverse は意図を認識できないため、これを防ぐ試みはありません。

イベントの単一バージョンに適用される同じロジックが、イベントの複数バージョンに移行され、イベントの単一バージョンから削除されるよう確認してください。 それ以外の場合、ロジックは 2 回適用されます。

CreateMultiple および UpdateMultiple (プレビュー) のプラグインを記述する方法について説明します

制限

一括操作メッセージを使用する場合は、次の制限事項に留意してください。

メッセージのサイズと時間制限

標準テーブルの場合、各要求でより多くのレコードを送信すると、パフォーマンスが向上します。 ただし、ペイロードのサイズと操作の処理にかかる時間によって、送信できるレコードの数が制限されます。

メッセージ サイズの制限

メッセージのプラグインを登録すると、要求の合計サイズが 116.85 MB を超えると 、"サンドボックスにコンテキストを送信するときにメッセージ サイズが超過しました" というエラーが発生する可能性があります。 一括操作メッセージを使用すると、より大きなペイロードを送信するため、この制限に簡単に到達できます。

このエラーは、イベントのプラグインを登録しない場合は発生しません。 このエラーを回避するには、プラグインを無効にするか、 BypassCustomPluginExecution 省略可能なパラメーターを使用して要求を送信します。

時間の制限

Dataverse ServiceClient を使用すると、次のエラーが発生する可能性があります。

The request channel timed out attempting to send after 00:04:00. 
Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. 
The time allotted to this operation may have been a portion of a longer timeout.

ServiceClient を使用して設定される既定のタイムアウトは 4 分です。これは、すべての同期操作に対して長い時間です。 この値は、静的 ServiceClient.MaxConnectionTimeout プロパティを使用して変更できます。 CrmServiceClient を使用した既定のタイムアウトは 2 分です。

ヒント

時間制限を増やす前に、 Targets パラメーターで渡すレコードの数を減らすことを検討してください。

プラグインでの使用はサポートされていない

現時点では、Dataverse はプラグイン コードでの一括操作メッセージの使用をサポートしていません。 詳細については、「 プラグインとワークフロー アクティビティでバッチ要求の種類を使用しない」を参照してください。

ただし、CreateMultiple と UpdateMultiple のプラグイン で説明されているように、CreateMultiple および UpdateMultiple のメッセージ用のプラグインを作成する 必要があります

一般的なエラーのトラブルシューティング

一括操作の使用中にエラーが発生した場合は、次の記事を参照してください。

よくあるご質問 (FAQ)

この記事で一括操作メッセージの使用に関する質問への回答が見つからい場合は、このページの下部にあるボタンを使用して、このページに対するフィードバックを送信して表示します。 フィードバックを送信するには、GitHub アカウントが必要です。

Retrieve ロジックと RetrieveMultiple ロジックはマージされますか?

Microsoft では、 RetrieveRetrieveMultiple メッセージの動作を変更する予定はありません。 これらのメッセージは長年にわたって個別のメッセージであり、開発者は常に個別にロジックを維持する必要があります。 これらのメッセージ パイプラインを統合しようとすることは、大きな問題です。 また、 パフォーマンスに影響を与える可能性があるため、これらのメッセージにカスタム ロジックを適用しないでください。

API の制限はどのように適用されますか?

2 種類の API 制限が適用されます。 一括操作メッセージでは、どのタイプを回避する方法も提供されません。

サービス保護の制限

サービス保護 API の制限 で説明されているように、制限には 3 つの側面があります。 これらの制限のうち 2 つは、5 分間のスライディング ウィンドウで評価され、これらのメッセージを使用するときに適用されます。

  • リクエスト数: 各一括操作メッセージは 1 つのリクエストとしてカウントされ、五分間のウィンドウ内でユーザーごと、サーバーごとに 6,000 リクエスト件の上限まで累積します。 これらのリクエストは個々の操作をグループ化するため、この制限に達する可能性は低くなります
  • 実行時間: 通常、各一括操作メッセージのリクエストには時間がかかるため、リクエストを並行して送信している場合は、五分間の時間枠内で、ユーザーごと、サーバーごとに 20 分という実行時間制限に達する可能性が高くなります

Power Platform リクエスト (API 使用権) の制限

これらの制限はデータの変更に基づいています: CreateUpdateDelete 操作。 一括操作リクエストの Targets パラメータに含まれる各項目は、この制限まで加算されます。 要求の制限と割り当てに関する詳細

参照

エラスティック テーブル
CreateMultiple と UpdateMultiple のプラグインを書き込む
サンプル: .NET 用 SDK 一括操作の使用
サンプル: Web API 一括操作の使用
サンプル: CreateMultiple および UpdateMultiple プラグイン
.NET 用 SDK でメッセージを使用する
一括操作で最適化されたパフォーマンス