コードを使用してエラスティック テーブルを使用する
この記事では、コードを使用して、エラスティック テーブルで一括データ操作を実行する方法について解説します。
セッション トークンの操作
一貫性レベル で述べたように、リクエストに現在のセッショントークンを渡すことで、セッションレベルの整合性を実現することができます。 セッション トークンを含めない場合、取得したデータに、直前に行ったデータ変更が含まれない可能性があります。
セッション トークンの取得
セッション トークンは、すべての書き込み操作のレスポンスに表示されます。 x-ms-session-token
値を探します。
書き込み操作を行う OrganizationResponse については、結果 コレクションに x-ms-session-token
値を取り込むことができます。
注意
現在、DeleteResponse は、x-ms-session-token
値を返しません。 詳細については、既知の問題: 削除操作に対して x-ms-session-token no の値が返されないを参照してください。
string sessionToken = response.Results["x-ms-session-token"].ToString();
セッション トークンの送信
読み取り操作でセッション トークンを送信する方法は、SDK を使用しているか Web API を使用しているかによって異なります。
データを取得する操作を行う際、OrganizationRequest に SessionToken
オプションのパラメーターを設定します。
var request = new RetrieveRequest
{
Target = new EntityReference("contoso_sensordata", sensordataid),
ColumnSet = new ColumnSet("contoso_value"),
["partitionId"] = deviceId,
["SessionToken"] = sessionToken
};
PartitionId を指定する
パーティショニングと水平スケーリング で説明されているように、各エラスティック テーブルには、テーブルのパーティション分割戦略を適用する場合に使用しなければならない partitionid
列があります。 それ以外の場合は、partitionid
列に値を設定しないでください。
重要
エラスティック テーブルにパーティション分割方法を使用することを選択した場合、そのテーブルに対するすべての操作、またはそのテーブル内のレコードの参照は、レコードを一意に識別するために partitionid
列の値を指定する 必要 があります。 参照テーブルのルックアップ値に partitionid
が指定されていない場合エラーはスローされませんが、使用時にルックアップがレコードを見つけることができません。 データに一貫性があり、すべての操作に partitionid
が適切に使用されていることを確認するには、コード レビューを通じてこの要件を文書化して適用する必要があります。
行の作成時に partitionid
列に非 null の値を指定した後、その行に対して他のデータ操作を行う際にそれに指定する必要があります。 値は後で変更できます。
レコードの作成時に partitionid
値を設定しない場合、partitionid
列の値は null のままになり、後で変更することはできません。 この場合、標準テーブルで通常行うのと同様に、主キーを使用することによりレコードを識別できます。 partitionid
値の指定は不要です。
注意
この記事の例では、partitionid
列に null 以外の値を指定していると仮定しています。
さまざまなデータ操作を実行するときに、次の方法で partitionid
値を設定できます。
代替キーの使用
代替キー で説明したように、すべてのエラスティック テーブルには、KeyForNoSqlEntityWithPKPartitionId
という名前の代替キーがあります。 この 代替キー は、テーブルの主キーを partitionid
列と結合します。
パーティション分割方法を使用している場合は、Retrieve
、Update
、または Delete
操作を使用するとき、またはエラスティック テーブル レコードを参照する別のテーブルのルックアップ列を設定するときに、代替キー を指定して partitionid
値を指定する必要があります。
この例では、エラスティック テーブルで Retrieve
、Update
、Delete
リクエストを使用するときに代替キーを使用して partitionid
を指定する方法を示します。
var keys = new KeyAttributeCollection() {
{ "contoso_sensordataid", sensordataid },
{ "partitionid", deviceId }
};
var entity = new Entity("contoso_sensordata", keys)
partitionId パラメーターを使用する
現在、partitionId
パラメータを使用して、 partitionid
および Retrieve
操作の場合にのみ Delete
列の値を指定できます。 詳細については、既知の問題: partitionId オプション パラメータがすべてのメッセージで使用できないを参照してください。
注意
partitionId
パラメーターは、Create
、Update
、または Upsert
メッセージでは機能せず、送信されても無視されます。
request["partitionId"] = "device-001"
Partitionid 列を直接使用する
Create
、Upsert
、または Update
操作では、 partitionid
列の値を直接指定できます。
この例では、Create
、Upsert
、Update
の操作を実行する際に、Entity
の partitionid
列の値を直接指定する方法を示しています。
var entity = new Entity("contoso_sensordata", sensordataid)
{
Attributes = {
{ "partitionid", "device-001" }
}
};
エラスティック テーブルでレコードを作成する
この例では、partitionid
を deviceid
に設定して contoso_SensorData
テーブルに行を作成します。 また、行が 1 日 (86,400 秒) 後に期限切れになり、ttlinseconds
から自動的に削除されるようにする Dataverse 列も設定します。
この例では、作成されたレコードを取得するときに使用できる x-ms-session-token
値もキャプチャします。
/// <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;
}
作成したレコードを取得するときに、返された x-ms-session-token
値を使用して SessionToken
オプションのパラメーターを設定します。 セッション トークンの送信に関する詳細については、こちらをご覧ください。
注意
エラスティック テーブルでディープ挿入 は現在サポートされていません。 関連する各レコードは個別に作成する必要があります。 標準テーブルのみがディープ挿入をサポートします
主キー値の設定
主キー値を指定しない場合は、Dataverse レコードを作成するときに、レコードの主キー値を設定します。 Dataverse にこの値を設定させるのが通常の方法です。 必要に応じて、主キーの値を指定できます。 伸縮自在なテーブルの場合、Dataverse 主キーの値を設定します。
エラスティック テーブルは、一意ではない主キー値を持つレコードを作成してもエラーを返しません。 エラスティック テーブルで主キー値を設定することで、同じ主キー値と異なる partitionid
値を持つレコードを作成できます。 ただし、このパターンは Power Apps と互換性がありません。 キャンバスまたはモデル駆動型アプリでこのデータを使用する必要がある場合は、重複する主キー値を持つレコードを作成しないでください。
エラスティック テーブルでレコードを更新する
この例では、contoso_sensordataid
の主キーと partitionid
= 'device-001'
を使用して、contoso_SensorData
テーブルの既存の行の contoso_value
と contoso_timestamp
の値を更新します。
パーティション分割戦略を使用している場合は、既存のエラスティック テーブル行を一意に識別するために主キーと partitionid
列が必要です。 既存の行の partitionid
値は更新できず、更新する行を一意に識別するためにのみ使用されています。
この例では、KeyForNoSqlEntityWithPKPartitionId
代替キー を使用して、主キーと partitionid
値の両方を使用してレコードを一意に識別します。 代替キーについては、次をご覧ください。
この例は、partitionid
値を代替キーとして使用する方法を示しています。
/// <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();
}
エラスティック テーブルでレコードを取得する
エラスティック テーブル レコードが作成されたときに partitionid
値が設定された場合、レコードを一意に識別するために、 値を主キー値とともに使用する必要があります。
partitionid
が設定されていない場合は、主キー値のみを使用することにより、通常の方法でレコードを取得できます。
partitionid
値を使用することによってレコードを取得するリクエストを作成するには、2 つの異なる方法があります。
この例では、RetrieveRequest クラスを使用します。 Target
プロパティは、KeyForNoSqlEntityWithPKPartitionId
代替キーを使用するために KeyAttributeCollection を受け入れるコンストラクターを使用して作成した EntityReference に設定されています。 EntityReference クラスを使用して代替キーを設定する方法については、こちらをご覧ください。
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")}");
}
この例では、RetrieveRequest クラス で partitionId
というオプションのパラメーターを使用しています。 オプションのパラメーターの使用については、次を参照してください。
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")}");
}
エラスティック テーブルのクエリ行
エラスティック テーブルの行をクエリする場合、クエリを特定のパーティションに限定すると、最高のパフォーマンスが得られます。 それ以外の場合、クエリはすべての論理パーティションにわたるデータを返すため、速度が遅くなります。
注意
このアプローチを使用する場合、パラメーターには、partitionid
(すべて小文字) ではなく partitionId
(大文字の I) という名前を使用する必要があります。
この方法でフィルターを指定すると、通常の方法 (つまり、 partitionid
、 FetchXML condition
QueryExpression ConditionExpression 、またはWeb API を使用する) でクエリにフィルター条件を指定する必要がなくなります。 $filter
通常の方法で partitionid
値にフィルターを指定しても、次の例に示すように partitionId
パラメーターで指定する場合と同じパフォーマンス上の利点はありません。
これらの例では、contoso_SensorData
テーブルのうち、partitionid
= 'deviceid-001'
である論理パーティションに属する最初の 5000 行を取得するものです。
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;
}
クエリで関連する行を返す
エラスティック テーブルは現在、クエリ実行時に関連する行を返すことはできません。 関連する行を返そうとすると、Dataverse はコード 0x80048d0b
のエラーと次のメッセージをスローします。
Link entities are not supported
。
しかし、エラスティック テーブルは、1 つの行の取得時に、関連する行を返すことはサポートしています。
エラスティック テーブルでレコードをアップサートする
重要
エラスティック テーブルでの更新/挿入操作は、標準テーブルのアップサート操作とは異なります。 アップサート操作には完全なペイロードが含まれることが想定されており、既存のレコード データは上書きされます。 Create
または Update
メッセージは呼び出されません。 エラスティック テーブルのアップサートについては、 次をご覧ください。
エラスティック テーブルでは、指定された ID と partitionid
を持つレコードが存在しない場合、そのレコードが作成されます。 すでに存在する場合は置き換えられます。
この例では、contoso_SensorData
テーブルの行を指定された id
値と 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;
}
エラスティック テーブルでレコードを削除する
カスタム partitionid
値を使用するレコードを削除する場合、partitionid
値も含める必要があります。
この例では、SensorData テーブルに指定された ID =contoso_SensorData
と 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();
}
エラスティック テーブル レコードの関連付け
テーブル レコードが、partitionid
列の値が null であるエラスティック テーブル レコードを参照している場合、標準レコードと同様に、そのテーブルのレコードをエラスティック テーブル レコードに関連付けることができます。 .NET 用 SDK、または Web API を参照してください。
テーブル レコードが partitionid
列値が設定されたエラスティック テーブル レコードを参照する場合、参照元テーブルのルックアップ列を設定するときに、エラスティック テーブル レコードの partitionid
列値を含める必要があります。 これを行うには、値を代替キーとして含めます。
参照テーブルの Partitionid 値列 で説明されているように、1 対多の関連付けが作成され、エラスティック テーブルが 被参照 テーブルである場合、文字列の列およびルックアップ列が 参照 テーブルに作成されます。 文字列の列には、参照されるエラスティック テーブル レコードの partitionid
値が格納されます。
次の方法で、ルックアップと文字列の列値の両方にそれぞれの値を設定することができます:
- 代替キー参照を使用してルックアップのみを設定する
- 1 回の更新で 2 つの列の値を一緒に設定する
この方法は、.NET 用 SDK と Web API のどちらを使用しているかによって異なります
この例では、ルックアップ列に代替キーを設定することで、指定した ID と partitionid
を持つエラスティック contoso_SensorData
テーブル レコードを既存のアカウント レコードに関連付けます:
/// <summary>
/// Demonstrates associate to elastic table 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="deviceId">The deviceId. PartitionId of sensor data record.</param>
/// <param name="accountId">The unique identifier of the account record to update.</param>
public static void AssociateAccountAlternateKeyExample(
IOrganizationService service,
Guid sensordataId,
string deviceId,
Guid accountId)
{
var keys = new KeyAttributeCollection() {
{ "contoso_sensordataid", sensordataId },
{ "partitionid", deviceId }
};
var sensorDataReference = new EntityReference("contoso_sensordata", keys);
Entity account = new("account", accountId)
{
Attributes =
{
{"contoso_sensordata", sensorDataReference}
}
};
service.Update(account);
}
この例では同じことを行いますが、両方の列を一緒に設定します:
/// <summary>
/// Demonstrates associate to elastic table 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="deviceId">The deviceId. PartitionId of sensor data record.</param>
/// <param name="deviceId">The unique identifier of the account record to update.</param>
public static void AssociateAccountBothColumnsExample(
IOrganizationService service,
Guid sensordataId,
string deviceId,
Guid accountId)
{
Entity account = new("account", accountId) {
Attributes =
{
{"contoso_sensordata", new EntityReference("contoso_sensordata", sensordataId)},
{"contoso_sensordatapid", deviceId }
}
};
service.Update(account);
}
最後に、この例では、AssociateRequest を使用して、account
レコードのコレクションを同じ contoso_SensorData
テーブル レコードに 1 回の操作で関連付けることを示します。
/// <summary>
/// Demonstrates associating multiple accounts to a contoso_sensordata elastic table record
/// </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 deviceId. PartitionId of sensor data record.</param>
/// <param name="relatedEntities">A collection of references to account records to associate to the contoso_sensordata elastic table record</param>
public static void AssociateMultipleElasticTableExample(
IOrganizationService service,
Guid sensordataId,
string deviceId,
EntityReferenceCollection relatedEntities)
{
// The keys to the elastic table record including the partitionid
var keys = new KeyAttributeCollection() {
{ "contoso_sensordataid", sensordataId },
{ "partitionid", deviceId }
};
AssociateRequest request = new()
{
Target = new EntityReference("contoso_sensordata", keys),
Relationship = new Relationship("contoso_SensorData_contoso_SensorData_Acc"),
RelatedEntities = relatedEntities
};
service.Execute(request);
}
エラスティック テーブルを使用した一括操作
多くの場合、アプリケーションは短時間に大量のデータを Dataverse に取り込む必要があります。 Dataverse には、高スループットに対応したメッセージのグループがあります。 伸縮性のあるテーブルを使用すると、スループットがさらに向上します。
一括操作は、同じテーブルに対して複数の書き込み操作を実行する際、1 回の書き込み操作で一括で行を入力することでパフォーマンスを最適化するものです。 一括操作メッセージ (プレビュー) の詳細については、次をご覧ください。
エラスティック テーブルで CreateMultiple を使用する
CreateMultiple
メッセージは、SDK for .NET または Web API で使用できます。
この例では、CreateMultipleRequest クラスを使用して 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);
}
エラスティック テーブルで UpdateMultiple を使用する
UpdateMultiple
メッセージは、SDK for .NET または Web API で使用できます。
この例では、UpdateMultipleRequest クラスを使用して contoso_SensorData
エラスティック テーブルで複数の行を更新します。 これらの更新により、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);
}
エラスティック テーブルで DeleteMultiple を使用する
DeleteMultiple
メッセージは、SDK for .NET または Web API で使用できます。
注意
SDK には現在 DeleteMultipleRequest
クラスがないため、SDK では OrganizationRequest クラス を使用する必要があります。 .NET 用 SDK でメッセージを利用する詳細については、次をご覧ください。
次の DeleteMultipleExample
静的算出方法では、DeleteMultiple
メッセージを OrganizationRequest class と併用して、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);
}
次の手順
コードを使用して、エラスティック テーブルの JSON 列に JavaScript Object Notation (JSON) データを作成し、クエリする方法を学習します。
参照
開発者向けエラスティック テーブル
コードを使用してエラスティック テーブルを作成する
エラスティック テーブルの JSON 列をクエリする
エラスティック テーブルのサンプル コード
一括操作メッセージ (プレビュー)