[この記事はプレリリース ドキュメントであり、変更されることがあります。]
ユーザーが削除すべきではないレコードを削除する場合があります。 管理者は、指定した期間内に削除されたレコードを復元できるように、テーブルのごみ箱を有効にすることができます。 管理者が削除されたレコードを復元する方法について説明します
ごみ箱が有効になっている場合、開発者は Restore メッセージを使用して、指定した期間前に削除されたレコードを復元できます。 期間は最大 30 日間です。
復元できる削除済みレコードを取得する
復元できる削除されたレコードを取得するには、クエリのデータソースを "bin" に設定します。
次の例では、削除されたアカウント レコードを最大 3 つ返します。
SDK を使用する場合は、 FetchXml または QueryExpression を使用してデータを取得できます。
FetchXml を使用してデータを取得する場合は、レコードを取得するときに fetch 要素datasource 属性を 'bin' に設定します。
static EntityCollection GetDeletedAccountRecordsFetchXml(IOrganizationService service) {
string queryString = @"<fetch top='3' datasource='bin'>
<entity name='account'>
<attribute name='name' />
</entity>
</fetch>";
FetchExpression query = new(queryString);
return service.RetrieveMultiple(query);
}
QueryExpression を使用してデータを取得する場合は、レコードを取得するときに QueryExpression.DataSource プロパティを 'bin' に設定します。
static EntityCollection GetDeletedAccountRecordsQueryExpression(IOrganizationService service) {
QueryExpression query = new("account") {
ColumnSet = new ColumnSet("name"),
DataSource = "bin",
TopCount = 3
};
return service.RetrieveMultiple(query);
}
削除されたレコードを復元する
Restore メッセージを使用して、削除されたレコードを復元します。
Target パラメーターは削除されたレコードへの参照ではなく、完全なレコードであるため、レコードの復元中に列の値を設定できます。
Restore操作中に値を設定してオーバーライドしない限り、元の列の値はすべて復元されます。
注
現時点では、主キー値を使用してのみレコードを復元できます。 代替キーを使用してレコードを復元することはできません。
削除されたレコードを復元する方法は、SDK for .NET と Web API のどちらを使用しているかによって異なります。
SDK for .NET を使用してレコードを復元する方法は、 pac modelbuilder を使用して早期バインド型を生成しているか、遅延バインド スタイルを使用しているかによって異なります。
遅延バインディングおよび早期バインドプログラミングの方法について、.NET の SDK を使用して学びます
早期バインドの例
静的RestoreAccountRecordEarlyBound メソッドは、RestoreRequest<T> を使用して生成されたAccountクラスと クラスを使用します。
/// <summary>
/// Restores an account record
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance</param>
/// <param name="accountId">The ID of the deleted account record.</param>
/// <param name="originalName">The original name value for the account record.</param>
/// <returns>The ID of the restored account</returns>
static Guid RestoreAccountRecordEarlyBound(
IOrganizationService service,
Guid accountId,
string originalName)
{
Account accountToRestore = new()
{
Id = accountId,
// Appending '(Restored)' to the original name
// to demonstrate overwriting a value.
Name = originalName + " (Restored)"
};
RestoreRequest<Account> request = new()
{
Target = accountToRestore
};
var response = (RestoreResponse)service.Execute(request);
return response.id;
}
遅延バインドの例
静的 RestoreAccountRecordLateBound メソッドは 、OrganizationRequest クラスを使用して Restore メッセージを呼び出し、 Target パラメーターを設定します。
/// <summary>
/// Restores an account record
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance</param>
/// <param name="accountId">The ID of the deleted account record.</param>
/// <param name="originalName">The original name value for the account record.</param>
/// <returns>The ID of the restored account</returns>
static Guid RestoreAccountRecordLateBound(
IOrganizationService service,
Guid accountId,
string originalName)
{
Entity accountToRestore = new("account", accountId)
{
Attributes = {
// Appending '(Restored)' to the original name
// to demonstrate overwriting a value.
{"name", originalName + " (Restored)"}
}
};
OrganizationRequest request = new("Restore")
{
Parameters = {
{ "Target", accountToRestore }
}
};
OrganizationResponse response = service.Execute(request);
return (Guid)response.Results["id"];
}
レコードを復元するときのベスト プラクティス
レコードを復元するときに回避できる問題を次に示します。
- プライマリ レコードを復元する前に関連レコードを復元する
- レコードの作成時に主キー値を指定しない
- 代替キー値が一致するレコードによって復元がブロックされる
- 削除された選択肢オプションを使用するレコードが復元されない
- 削除時の主キー違反
プライマリ レコードを復元する前に関連レコードを復元する
連鎖リレーションシップの一部として参照が削除された関連レコードが存在しなくなった場合、復元操作は失敗します。 この問題を回避するには、プライマリ レコードを復元する前に、現在のレコードの一部として削除されていない関連レコードを常に復元してください。
名前:
RefCannotBeRestoredRecycleBinNotFound
コード:0x80049959
数:-2147182247
メッセージ:Entity with id '<Guid Value>' and logical name '<Entity.LogicalName>' does not exist. We cannot restore the reference '<Referred Primary Key Name>' that must be restored as part of this Restore call. ValueToBeRestored: <Guid Value>, ReferencedEntityName: <Referenced Entity Name>, AttributeName: <Referred Attribute Name>
レコードの作成時に主キー値を指定しない
通常は、レコードの作成時に常に Dataverse に主キーを設定することをお勧めします。 削除されたレコードと同じ主キー値を持つ新しいレコードを作成した場合、削除されたレコードは復元できません。 その場合は、削除したレコードを復元する前に、新しいレコードを削除する必要があります。
名前:
DuplicateExceptionRestoreRecycleBin
コード:0x80044a02
数:-2147182279
メッセージ:Please delete the existing conflicting record '<Entity Platform Name>' with primary key '<Primary Key Name>' and primary key value '<Primary Key Value>' before attempting restore.
代替キー値が一致するレコードによって復元がブロックされる
削除されたレコードと同じ代替キー列の値を持つレコードを作成した場合、復元することはできません。 その場合は、削除したレコードを復元する前に、新しいレコードを削除する必要があります。
名前:
DuplicateExceptionEntityKeyRestoreRecycleBin
コード:0x80049929
数:-2147182295
メッセージ:Duplicate entity key preventing restore of record '<Entity Platform Name>' with primary key '<Primary Key Name>' and primary key value '<Primary Key Value>'. See inner exception for entity key details.
削除された選択肢オプションを使用するレコードが復元されない
オプション セット オプションを削除し、そのオプションが削除されたレコードで使用されていた場合、そのオプションが無効になったため、復元できません。 オプション セット オプションを削除する前に、削除されたレコードを含め、そのオプションを使用するレコードがないことを確認します。
名前:
PicklistValueOutOfRangeRecycleBin
コード:0x80049949
数:-2147182263
メッセージ:Picklist value not valid, please add the invalid value back to the picklist before restoring record
削除時の主キー違反
同じ主キーを持つレコードが既に削除されている場合、そのレコードのごみ箱へのコピーは無視されます。 削除されたすべてのアイテムがごみ箱に格納されるようにするには、DoNotEnforcePrimaryKeyOrgSettingRecycleBinを使用して設定を設定します。
この設定を有効にすると、次のエラーが表示されることがあります。
名前:
DuplicateExceptionRestoreRecycleBin
コード:0x80049939
数:-2147182279
メッセージ:A record that has the attribute values Deleted Object already exists on Delete.
ごみ箱に対して有効になっているテーブルを検出する
ごみ箱機能を有効にする前に、 ごみ箱の構成 (RecycleBinConfig) テーブル には行がありません。
最終的には、ほとんどのテーブルでごみ箱機能を使用できるようになる予定です。 ソリューション コンポーネント、 仮想テーブル、 エラスティック テーブル は、ごみ箱ではサポートされていません。 このプレビュー期間中は、現在有効になっていない一部のテーブルが後で有効になる場合があります (たとえば、400 列を超えるテーブルなど)。 ごみ箱をサポートしていないテーブルの一覧については、「ごみ箱で 現在サポートされていないテーブル」を参照してください。
特定のテーブルのごみ箱を無効にしたり、環境のごみ箱を無効にしたりすることもできます。 テーブルのごみ箱が有効になっていない場合、復元対象の レコードは見つかりません。 Dataverse にクエリを実行して、ごみ箱がテーブルに対して有効になっているかどうかを確認できます。
ごみ箱が有効になっているテーブルの RecycleBinConfig テーブルには、 statecode がアクティブで、 isreadyforrecyclebin が true の行があります。
RecycleBinConfig テーブルにはテーブルの名前は含まれませんが、Entity テーブル内の行を参照します。この場合、logicalname列にはテーブルの LogicalName が含まれます。
次の FetchXml クエリを使用して、ごみ箱が有効になっているテーブルを検出します。
<fetch>
<entity name='recyclebinconfig'>
<filter type='and'>
<condition attribute='statecode'
operator='eq'
value='0' />
<condition attribute='isreadyforrecyclebin'
operator='eq'
value='1' />
</filter>
<link-entity name='entity'
from='entityid'
to='extensionofrecordid'
link-type='inner'
alias='entity'>
<attribute name='logicalname' />
<order attribute='logicalname' />
</link-entity>
</entity>
</fetch>
FetchXml を使用してデータのクエリを実行する方法について説明します
ごみ箱が有効になっていないテーブルを検出する
ごみ箱に対して有効になっていないテーブルを確認するには、次の FetchXml クエリを使用します。これは、「 ごみ箱で有効になっているテーブルを検出する」の逆のクエリです。
<fetch>
<entity name='entity'>
<attribute name='logicalname' />
<filter type='or'>
<condition entityname='recyclebin'
attribute='extensionofrecordid'
operator='null' />
<condition entityname='recyclebin'
attribute='statecode'
operator='ne'
value='0' />
<condition entityname='recyclebin'
attribute='isreadyforrecyclebin'
operator='ne'
value='1' />
</filter>
<order attribute='logicalname' />
<link-entity name='recyclebinconfig'
from='extensionofrecordid'
to='entityid'
link-type='outer'
alias='recyclebin' />
</entity>
</fetch>
FetchXml を使用してデータのクエリを実行する方法について説明します
このプレビュー機能が開始された 2024 年 5 月時点のこのクエリの結果は、現在ごみ箱でサポートされていないテーブルにあります
ごみ箱の自動クリーンアップ期間の構成を取得して設定する
削除されたレコードを復元できる期間を決定する値は、[名前] 列の値がされている organization 列に設定されます。
RecycleBinConfig テーブルの 1 行おきに、CleanupIntervalInDays 列の値 -1 が含まれます。 この値は、 organization テーブルに設定されているのと同じ値を使用したことを示します。
別のテーブルに別の値を指定するには、CleanupIntervalInDaysがテーブルの論理名と一致するName列の値を設定します。 この列では最大 30 の値を使用できます。組織の既定値と異なる場合を除き、設定しないことをお勧めします。
この静的 SetCleanupIntervalInDays メソッドを使用して、特定のテーブルの CleanupIntervalInDays 列の値を設定できます。
/// <summary>
/// Updates the CleanupIntervalInDays value for a specified table
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance</param>
/// <param name="entityId">The entityId of the table</param>
/// <param name="cleanupIntervalInDays">The new CleanupIntervalInDays value</param>
static void SetCleanupIntervalInDays(
IOrganizationService service,
Guid entityId,
int cleanupIntervalInDays)
{
QueryExpression query = new("recyclebinconfig")
{
ColumnSet = new ColumnSet("recyclebinconfigid"),
Criteria = new FilterExpression(LogicalOperator.And)
{
Conditions = {
{
new ConditionExpression(
attributeName: "extensionofrecordid",
conditionOperator: ConditionOperator.Equal,
value: entityId)
}
}
}
};
EntityCollection records = service.RetrieveMultiple(query);
if (records.Entities.Count.Equals(1))
{
Guid id = records.Entities[0].Id;
Entity record = new(entityName: "recyclebinconfig", id: id)
{
Attributes = {
{ "cleanupintervalindays", cleanupIntervalInDays }
}
};
service.Update(record);
}
else
{
throw new Exception($"Recycle bin configuration for table '{tableLogicalName}' not found.");
}
}
テーブルのごみ箱を無効にする
テーブルのごみ箱を無効にするには、recyclebinconfig プロパティと statuscode プロパティをそれぞれ非アクティブな値 (と2) に設定して、テーブルの1 レコードを無効にします。
注
次のクエリでは、 EntityId 値と Entity.EntityId 列の値が比較されます。この列には EntityMetadata.MetadataId テーブルが格納されます。
この静的 DisableRecycleBinForTable メソッドを使用して、特定のテーブルのごみ箱を無効にします。
/// <summary>
/// Disable the Recycle bin for a specified table
/// </summary>
/// <param name="service">The authenticated IOrganizationService instance</param>
/// <param name="tableEntityId">The entityId of the table</param>
static void DisableRecycleBinForTable(
IOrganizationService service,
Guid tableEntityId)
{
QueryExpression query = new("recyclebinconfig")
{
ColumnSet = new ColumnSet("recyclebinconfigid")
};
LinkEntity entityLink = query.AddLink(
"entity",
"extensionofrecordid",
"entityid");
entityLink.LinkCriteria.AddCondition(
"extensionofrecordid",
ConditionOperator.Equal,
tableEntityId);
EntityCollection recyclebinconfigs = service.RetrieveMultiple(query);
if (recyclebinconfigs.Entities.Count.Equals(1))
{
var id = recyclebinconfigs.Entities[0].GetAttributeValue<Guid>("recyclebinconfigid");
Entity recyclebinconfig = new("recyclebinconfig", id)
{
Attributes = {
{ "statecode", new OptionSetValue(1) },
{ "statuscode", new OptionSetValue(2) }
}
};
service.Update(recyclebinconfig);
}
else
{
string message = $"Recycle bin configuration for table '{extensionofrecordid}' not found.";
throw new Exception(message);
}
}
環境のごみ箱を無効にする
注
環境のごみ箱を無効にするには、 Power Platform 管理センターでごみ箱を無効にすることをお勧めします。 この機能が一般公開される前に、ここで説明する方法が変更される可能性があります。
値がnameされている "organization" テーブルの行を削除します。 これにより、 RecycleBinConfig テーブル内のすべてのレコードの削除がトリガーされ、環境のごみ箱が無効になります。
Important
他の個々のレコードを削除しないでください。 これを Dataverse が管理することが重要です。
カスタム ビジネス ロジックによって削除されたレコードの復元を管理する
Dataverse には、行が削除されたときに関連レコードに対して必要なアクションを管理するメカニズムが用意されています。 この構成データは、リレーションシップの定義の一部です。 関連レコードが削除されると、次の 4 つの動作を構成できます。
| 動作の削除 | Description |
|---|---|
| すべてカスケード | 関連レコードが削除されます。 |
| リンクの解除 | 削除されたレコードの参照列は null に設定されます。 |
| カスケードなし | 関連レコードに変更は適用されません。 (内部のみ) |
| 制限 | Dataverse では、データの整合性を維持するためにレコードを削除できなくなります。 このリレーションシップに関連するレコードがない限り、レコードを削除することはできません。 |
リレーションシップが Cascade All、 Remove Link、 Restrict に対して構成されている場合は、Dataverse がこれらの動作を管理するため、何もする必要はありません。
[リンクの削除] 動作を使用するようにリレーションシップを構成しているが、このリレーションシップで関連レコードを削除することが想定されている場合は、カスタムの動作を適用するカスタム ロジックが存在する可能性があります。 たとえば、この動作に異なる方法で応答し、定義したルールに基づいて独自の "Cascade some" 動作を実装することができます。 たとえば、一定期間更新されなかった非アクティブなレコードやレコードを削除できます。 通常、このロジックはプラグインを使用して実装されますが、Microsoft Dataverse コネクタで Power Automate を使用して実行することもできます。 行が追加、変更、または削除されたトリガーの場合。
この種のカスタム ビジネス ロジックがある場合、Dataverse はそのことを認識せず、ロジックを自動的に "元に戻す" ことができません。 ただし、 Restore メッセージに別のプラグインを登録して、カスタム ロジックを元に戻すことができます。 または、Power Automate と Microsoft Dataverse コネクタ: アクションが実行されたときにトリガーします。 を使用することもできます。
Important
Restore メッセージのプラグイン ステップを登録するときは、コンテキストに注意してください。 復元されるレコードは、 PreOperation ステージでは使用できません。 関連レコードを作成する必要がある場合は、 PostOperation ステージを使用します。
プラグイン ステージの詳細を確認します。
メッセージの InputParameters と Restore は、Create メッセージに似ているため、Create メッセージに登録するために書き込まれたプラグインは、変更を少なくしてRestore メッセージに再利用できます。
現在、ごみ箱でサポートされていないテーブル
「 ごみ箱が有効になっていないテーブルを検出する 」で説明されているクエリは、2024 年 8 月に この一覧 を生成するために使用されました。