Microsoft Dataverse では、 ETag と呼ばれる標準の HTTP リソースのバージョン管理メカニズムに依存する一連の条件付き操作がサポートされます。
ETags
HTTP プロトコルは、リソースの特定のバージョンを識別するための エンティティ タグ (略して ETag ) を定義します。 ETag は、正確な値が実装に依存する不透明な識別子です。 ETag 値は、強検証と弱検証の 2 種類で発生します。 厳密な検証は、対応する ETag 値が変更されていない場合、特定の URI によって識別される一意のリソースがバイナリ レベルで同一であることを示します。 弱い検証では、リソース表現が同じ ETag 値に対して意味的に同等であることが保証されるだけです。
Dataverse では、すべてのエンティティ インスタンスに対して弱い検証 @odata.etag プロパティが生成され、このプロパティは取得された各エンティティ レコードと共に自動的に返されます。 詳細については、「 Web API を使用してテーブル行を取得する」を参照してください。
If-Match および If-None-Match ヘッダー
ETag 値を持つ If-Match ヘッダーと If-None-Match ヘッダーを使用して、リソースの現在のバージョンが最後に取得されたものと一致するか、以前のバージョンと一致するか、またはバージョンと一致しないかを確認します。 これらの比較は、条件付き操作のサポートの基礎を形成します。 Dataverse には、条件付き取得、オプティミスティック コンカレンシー、および限定されたアップサート操作をサポートする ETag が用意されています。
Warnung
クライアントコードは、ETag の特定の値や、ETag 間の等しいか等しくないか以外の明確な関係に意味を与えてはなりません。 たとえば、リソースのより新しいバージョンの ETag 値は、以前のバージョンの ETag 値より大きいとは限りません。 また、新しい ETag 値の生成に使用されるアルゴリズムは、サービスのリリース間で予告なく変更される可能性があります。
条件付き取得
Etag を使用すると、同じレコードに複数回アクセスするたびにレコードの取得を最適化できます。 レコードを以前に取得した場合は、 If-None-Match ヘッダーと共に ETag 値を渡して、前回の取得以降に変更された場合にのみ、データの取得を要求できます。 データが変更された場合、要求は、要求の本文に最新のデータを含む 200 OK の HTTP 状態を返します。 データが変更されていない場合は、レコードが変更されていないことを示す HTTP 状態コード 304 Not Modified が返されます。
次のメッセージ ペアの例では、Etag 値が最後に取得されてからデータが変更されていない場合にaccountidと等しい00000000-0000-0000-0000-000000000001を持つアカウント レコードのデータを返します。W/"468026"
要求:
GET [Organization URI]/api/data/v9.2/accounts(00000000-0000-0000-0000-000000000001)?$select=accountcategorycode,accountnumber,creditonhold,createdon,numberofemployees,name,revenue HTTP/1.1
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: W/"468026"
応答:
HTTP/1.1 304 Not Modified
Content-Type: application/json; odata.metadata=minimal
OData-Version: 4.0
以降のセクションでは、条件付き取得の使用に関する制限について説明します。
テーブルでオプティミスティック コンカレンシーが有効になっている必要がある
次の Web API 要求を使用して、テーブルでオプティミスティック コンカレンシーが有効になっているかどうかを確認します。 オプティミスティック コンカレンシーが有効になっているテーブルでは 、EntityMetadata.IsOptimisticConcurrencyEnabled プロパティが true に設定されています。
GET [Organization URI]/api/data/v9.2/EntityDefinitions(LogicalName='<Entity Logical Name>')?$select=IsOptimisticConcurrencyEnabled
クエリに$expandを含めてはなりません
Etag は、取得される 1 つのレコードが変更された場合にのみ検出できます。 クエリで $expand を使用すると、より多くのレコードが返される可能性があり、それらのレコードが変更されたかどうかを検出することはできません。 クエリに $expandが含まれている場合、 304 Not Modified は返されません。
クエリに注釈を含めてはならない
Prefer: odata.include-annotations ヘッダーがGET要求に含まれている場合、304 Not Modifiedは返されません。 注釈の値は、関連するレコードの値を参照できます。 これらのレコードが変更され、この変更を検出できなかった可能性があるため、何も変更されていないことを示すには正しくありません。
アップサート操作を制限する
アップサートは通常、レコードが存在しない場合にレコードを作成することによって動作します。それ以外の場合は、既存のレコードが更新されます。 ただし、ETag を使用すると、アップサートをさらに制限して、作成を防いだり、更新を防いだりすることができます。
アップサートでの作成を禁止する
データを更新していて、レコードが意図的に削除された可能性がある場合は、レコードを再作成する必要はありません。 これを回避するには、If-Matchの値を持つ* ヘッダーを要求に追加します。
要求:
PATCH [Organization URI]/api/data/v9.2/accounts(00000000-0000-0000-0000-000000000001) HTTP/1.1
Content-Type: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
If-Match: *
{
"name": "Updated Sample Account ",
"creditonhold": true,
"address1_latitude": 47.639583,
"description": "This is the updated description of the sample account",
"revenue": 6000000,
"accountcategorycode": 2
}
応答:
レコードが見つかった場合は、状態 204 No Contentを含む通常の応答が表示されます。 レコードが見つからない場合、404 Not Found のステータスで次の応答が返されます。
HTTP/1.1 404 Not Found
OData-Version: 4.0
Content-Type: application/json; odata.metadata=minimal
{
"error": {
"code": "",
"message": "account With Id = 00000000-0000-0000-0000-000000000001 Does Not Exist"
}
}
アップサートで更新を禁止する
データを挿入する場合は、同じ id 値を持つレコードが既にシステムに存在し、更新したくない可能性があります。 これを回避するには、値が "*" の If-None-Match ヘッダーを要求に追加します。
要求:
PATCH [Organization URI]/api/data/v9.2/accounts(00000000-0000-0000-0000-000000000001) HTTP/1.1
Content-Type: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: *
{
"name": "Updated Sample Account ",
"creditonhold": true,
"address1_latitude": 47.639583,
"description": "This is the updated description of the sample account",
"revenue": 6000000,
"accountcategorycode": 2
}
応答:
レコードが見つからない場合は、204 No Content の状態で通常の応答が返されます。 レコードが見つかると、状態が 412 Precondition Failedされた次の応答が表示されます。
HTTP/1.1 412 Precondition Failed
OData-Version: 4.0
Content-Type: application/json; odata.metadata=minimal
{
"error":{
"code":"",
"message":"A record with matching key values already exists."
}
}
オプティミスティック コンカレンシーを適用する
オプティミスティック コンカレンシーを使用して、レコードが最後に取得されてから変更されたかどうかを検出できます。 更新または削除するレコードが取得後にサーバーで変更された場合は、更新または削除の操作を完了したくない場合があります。 ここで示すパターンを適用することで、この状況を検出し、レコードの最新バージョンを取得し、必要な条件を適用して、操作を再試行するかどうかを再評価できます。
削除時にオプティミスティック コンカレンシーを適用する
accountidが00000000-0000-0000-0000-000000000001のアカウントに対する次の削除要求は、If-Match ヘッダーで送信された ETag 値が現在の値と異なるため失敗します。 値が一致した場合は、 204 No Content 状態が予想されます。
要求:
DELETE [Organization URI]/api/data/v9.2/accounts(00000000-0000-0000-0000-000000000001) HTTP/1.1
If-Match: W/"470867"
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
応答:
HTTP/1.1 412 Precondition Failed
Content-Type: application/json; odata.metadata=minimal
OData-Version: 4.0
{
"error":{
"code":"","message":"The version of the existing record doesn't match the RowVersion property provided."
}
}
更新時にオプティミスティック コンカレンシーを適用する
accountid ヘッダーで送信された ETag 値が現在の値と異なるため、00000000-0000-0000-0000-000000000001のIf-Matchを持つアカウントに対する次の更新要求は失敗します。 値が一致した場合は、 204 No Content 状態が予想されます。
要求:
PATCH [Organization URI]/api/data/v9.2/accounts(00000000-0000-0000-0000-000000000001) HTTP/1.1
If-Match: W/"470867"
Accept: application/json
OData-MaxVersion: 4.0
OData-Version: 4.0
{"name":"Updated Account Name"}
応答:
HTTP/1.1 412 Precondition Failed
Content-Type: application/json; odata.metadata=minimal
OData-Version: 4.0
{
"error":{
"code":"","message":"The version of the existing record doesn't match the RowVersion property provided."
}
}
こちらも参照ください
Web API の条件付き操作のサンプル (C#)
Web API の条件付き操作のサンプル (クライアント側 JavaScript)
Web API を使用して演算を実行する
Http 要求を作成し、エラーを処理する
Web API を使用してデータのクエリを実行する
Web API を使用してテーブル行を作成する
Web API を使用してテーブル行を取得する
Web API を使用してテーブル行を更新および削除する
Web API を使用してテーブル行の関連付けと関連付けを解除する
Web API 関数を使用する
Web API アクションの使用
Web API を使用してバッチ操作を実行する
Web API を使用して別のユーザーを偽装する