メタデータへの変更の取得および検出

 

公開日: 2017年1月

対象: Dynamics 365 (online)、Dynamics 365 (on-premises)、Dynamics CRM 2016、Dynamics CRM Online

Microsoft.Xrm.Sdk.Metadata.Query 名前空間のクラスと RetrieveMetadataChangesRequest および RetrieveMetadataChangesResponse クラスで、有効なメタデータ クエリの構築と時間経過に伴って発生するメタデータへの変更の取得が可能です。

この文書で参照されるすべてのコード例は「サンプル: メタデータのクエリと変更の検出」にあります。

技術記事「JavaScript を使用したメタデータのクエリ」に、クライアント側コードでオブジェクトとメッセージを使用するための JavaScript ライブラリがあります。

このトピックの内容

メタデータの使用方法

必要なメタデータのみの取得

新規または変更済みのメタデータの取得

削除されたメタデータに関する情報の取得

メタデータの使用方法

メタデータで Microsoft Dynamics 365 のデータ モデリングの変更に合わせたアプリケーションを作成することができます。 メタデータは次の種類のアプリケーションで重要です。

  • クライアント アプリケーションの UI

  • 外部システムに Dynamics 365 データをマップする統合ツール

  • 開発ツール

Microsoft.Xrm.Sdk.Metadata.Query 名前空間のクラスを使用して軽量のクエリと永続メタデータ キャッシュ間に存在する設計を実行できます。

軽量のクエリ

軽量クエリの例には、Microsoft Dynamics 365 オプション セット (候補リスト) 属性で、現在のオプションを表示するための選択コントロールを設定するユーザー定義 Web リソース UI がある場合が含まれます。 使用可能なオプションが変更されると、コードを更新する必要があるため、これらのオプションはハード コードにするのは好ましくありません。 その代わり、メタデータから、オプション値とラベルを取得するクエリを作成できます。

Microsoft Dynamics 365 アプリケーション キャッシュからこのデータを直接取得する場合に、Microsoft.Xrm.Sdk.Metadata.Query クラスを使用できるため、このデータをキャッシュする必要はありません。

永続メタデータ キャッシュ

Microsoft Dynamics 365 サーバーから切断しているときに動作可能でなければならないアプリケーションがある場合や、モバイル アプリケーションなどのクライアントとサーバー間のネットワーク帯域幅の制限に影響を受けやすいアプリケーションがある場合、永続メタデータ キャッシュを実装することができます。

永続メタデータ キャッシュを使用すると、アプリケーションで最初の接続時に、必要なすべてのメタデータをクエリする必要があります。 次にそのアプリケーションにそのデータを保存します。 次にアプリケーションが接続する時には、最後のクエリからの差異のみを取得できます。これにより、送信する必要があるデータが少なくなり、アプリケーションを読み込んでいる間に、変更をメタデータ キャッシュに統合します。

メタデータの変更へのポーリング頻度は、アプリケーションのメタデータの変化予測と、アプリケーションの実行時間に基づいて決めます。 メタデータの変更がいつ発生するかの検出に使用できるイベントはありません。 検出されたメタデータの変更が保存される日数には制限があります。また、素の制限を超えて発生する変更要求があった場合、メタデータ キャッシュの完全再初期化が必要です。 詳細については、「削除されたメタデータの有効期限」を参照してください。

変更がない場合は、クエリはすぐに応答し、送信されるデータはありません。 ただし、特にキャッシュから削除される予定の削除済みメタデータ アイテムがある場合、その要求が終了するまでさらに時間がかかることが予想されます。詳細:削除されたメタデータを取得するときのパフォーマンス

必要なメタデータのみの取得

メタデータは、アプリケーションを起動した時に頻繁に取得または同期されるため、アプリケーションの読み込み時間に影響を与えます。 これは、メタデータを取得するのが初めてのモバイル アプリケーションで特に当てはまります。 必要なメタデータのみを取得することは、アプリケーションのパフォーマンスを向上させるために非常に重要です。

EntityQueryExpression クラスは、エンティティ データを取得する複雑なクエリを作成するときに使用する QueryExpression クラスと構造的に一貫しています。RetrieveAllEntitiesRequestRetrieveEntityRequestRetrieveAttributeRequest、または RetrieveRelationshipRequest クラスとは異なり、RetrieveMetadataChangesRequest には必要なプロパティに加えて返されるデータの特定の条件を指定するときに使用できる EntityQueryExpression インスタンスを受け入れる Query パラメーターが含まれます。RetrieveMetadataChangesRequest を使用して、RetrieveAllEntitiesRequest を使用して取得したメタデータのフル セットまたは特定の属性のラベルだけを返すことができます。

フィルターの条件の指定

EntityQueryExpression.Criteria プロパティは、値に基づいてエンティティのプロパティをフィルター処理するための要件を定義できる MetadataConditionExpression オブジェクトのコレクションを含む MetadataFilterExpression を受け取ります。 これらの要件では、以下の演算子で使用できる MetadataConditionOperator を使用します。

MetadataFilterExpression には、条件の評価時に And または Or ロジックを適用するかどうかを表す LogicalOperator も含まれます。

一部のプロパティをフィルターの条件として使用できます。 シンプルなデータ型、列挙体、BooleanManagedProperty または AttributeRequiredLevelManagedProperty 型を表すプロパティのみを MetadataFilterExpression で使用できます。BooleanManagedProperty または AttributeRequiredLevelManagedProperty を指定すると、Value プロパティだけが評価されます。

次の表は、MetadataFilterExpression で使用できない EntityMetadata プロパティを示します。

Attributes

Description

DisplayCollectionName

DisplayName

ManyToManyRelationships

ManyToOneRelationships

OneToManyRelationships

Privileges

次の例は、除外するエンティティの一覧に含まれない、交差するエンティティではないユーザー所有のエンティティのセットを返す MetadataFilterExpression を示します。



     // An array SchemaName values for non-intersect, user-owned entities that should not be returned.
     String[] excludedEntities = {
"WorkflowLog",
"Template",
"CustomerOpportunityRole",
"Import",
"UserQueryVisualization",
"UserEntityInstanceData",
"ImportLog",
"RecurrenceRule",
"QuoteClose",
"UserForm",
"SharePointDocumentLocation",
"Queue",
"DuplicateRule",
"OpportunityClose",
"Workflow",
"RecurringAppointmentMaster",
"CustomerRelationship",
"Annotation",
"SharePointSite",
"ImportData",
"ImportFile",
"OrderClose",
"Contract",
"BulkOperation",
"CampaignResponse",
"Connection",
"Report",
"CampaignActivity",
"UserEntityUISettings",
"IncidentResolution",
"GoalRollupQuery",
"MailMergeTemplate",
"Campaign",
"PostFollow",
"ImportMap",
"Goal",
"AsyncOperation",
"ProcessSession",
"UserQuery",
"ActivityPointer",
"List",
"ServiceAppointment"};

     //A filter expression to limit entities returned to non-intersect, user-owned entities not found in the list of excluded entities.
     MetadataFilterExpression EntityFilter = new MetadataFilterExpression(LogicalOperator.And);
     EntityFilter.Conditions.Add(new MetadataConditionExpression("IsIntersect", MetadataConditionOperator.Equals, false));
     EntityFilter.Conditions.Add(new MetadataConditionExpression("OwnershipType", MetadataConditionOperator.Equals, OwnershipTypes.UserOwned));
     EntityFilter.Conditions.Add(new MetadataConditionExpression("SchemaName", MetadataConditionOperator.NotIn, excludedEntities));
     MetadataConditionExpression isVisibileInMobileTrue = new MetadataConditionExpression("IsVisibleInMobile", MetadataConditionOperator.Equals, true);
     EntityFilter.Conditions.Add(isVisibileInMobileTrue);


' An array SchemaName values for non-intersect, user-owned entities that should not be returned.
                  Dim excludedEntities() As String =
                      {
                          "WorkflowLog",
                          "Template",
                          "CustomerOpportunityRole",
                          "Import",
                          "UserQueryVisualization",
                          "UserEntityInstanceData",
                          "ImportLog",
                          "RecurrenceRule",
                          "QuoteClose",
                          "UserForm",
                          "SharePointDocumentLocation",
                          "Queue",
                          "DuplicateRule",
                          "OpportunityClose",
                          "Workflow",
                          "RecurringAppointmentMaster",
                          "CustomerRelationship",
                          "Annotation",
                          "SharePointSite",
                          "ImportData",
                          "ImportFile",
                          "OrderClose",
                          "Contract",
                          "BulkOperation",
                          "CampaignResponse",
                          "Connection",
                          "Report",
                          "CampaignActivity",
                          "UserEntityUISettings",
                          "IncidentResolution",
                          "GoalRollupQuery",
                          "MailMergeTemplate",
                          "Campaign",
                          "PostFollow",
                          "ImportMap",
                          "Goal",
                          "AsyncOperation",
                          "ProcessSession",
                          "UserQuery",
                          "ActivityPointer",
                          "List",
                          "ServiceAppointment"
                      }

'A filter expression to limit entities returned to non-intersect, user-owned entities not found in the list of excluded entities.
Dim EntityFilter As New MetadataFilterExpression(LogicalOperator.And)
EntityFilter.Conditions.Add(New MetadataConditionExpression("IsIntersect", MetadataConditionOperator.Equals, False))
EntityFilter.Conditions.Add(New MetadataConditionExpression("OwnershipType", MetadataConditionOperator.Equals, OwnershipTypes.UserOwned))
EntityFilter.Conditions.Add(New MetadataConditionExpression("SchemaName", MetadataConditionOperator.NotIn, excludedEntities))
Dim isVisibileInMobileTrue As New MetadataConditionExpression("IsVisibleInMobile", MetadataConditionOperator.Equals, True)
EntityFilter.Conditions.Add(isVisibileInMobileTrue)

必要なプロパティの指定

Properties プロパティは MetadataPropertiesExpression を受け取ります。 すべてのプロパティを返す場合 MetadataPropertiesExpression.AllPropertiestrue に設定できます。または文字列のコレクションを MetadataPropertiesExpressionPropertyNames に提供して結果に含めるプロパティを定義することができます。

返される、厳密に型指定されたオブジェクトには、すべてのプロパティが含まれますが、要求したオブジェクトのみにデータがあります。 他のプロパティはすべて null ですが、いくつかの例外があります。メタデータの各アイテムはいずれも、そのアイテムの値が存在する場合は MetadataIdLogicalName および HasChanged の値が含まれます。 要求した Properties 内に指定する必要はありません。

マネージド コードを使用せず、XMLHttpRequest から返される responseXML を実際に分析する場合、各プロパティの要素が取得されますが、要求したものだけにデータが含まれます。 次の XML は IsVisibleInMobile が要求した唯一のプロパティの場合に返される、取引先担当者エンティティ メタデータを示します。

<a:EntityMetadata>
 <c:MetadataId>608861bc-50a4-4c5f-a02c-21fe1943e2cf</c:MetadataId>
 <c:HasChanged i:nil="true"/>
 <c:ActivityTypeMask i:nil="true"/>
 <c:Attributes i:nil="true"/>
 <c:AutoRouteToOwnerQueue i:nil="true"/>
 <c:CanBeInManyToMany i:nil="true"/>
 <c:CanBePrimaryEntityInRelationship i:nil="true"/>
 <c:CanBeRelatedEntityInRelationship i:nil="true"/>
 <c:CanCreateAttributes i:nil="true"/>
 <c:CanCreateCharts i:nil="true"/>
 <c:CanCreateForms i:nil="true"/>
 <c:CanCreateViews i:nil="true"/>
 <c:CanModifyAdditionalSettings i:nil="true"/>
 <c:CanTriggerWorkflow i:nil="true"/>
 <c:Description i:nil="true"/>
 <c:DisplayCollectionName i:nil="true"/>
 <c:DisplayName i:nil="true"/>
 <c:IconLargeName i:nil="true"/>
 <c:IconMediumName i:nil="true"/>
 <c:IconSmallName i:nil="true"/>
 <c:IsActivity i:nil="true"/>
 <c:IsActivityParty i:nil="true"/>
 <c:IsAuditEnabled i:nil="true"/>
 <c:IsAvailableOffline i:nil="true"/>
 <c:IsChildEntity i:nil="true"/>
 <c:IsConnectionsEnabled i:nil="true"/>
 <c:IsCustomEntity i:nil="true"/>
 <c:IsCustomizable i:nil="true"/>
 <c:IsDocumentManagementEnabled i:nil="true"/>
 <c:IsDuplicateDetectionEnabled i:nil="true"/>
 <c:IsEnabledForCharts i:nil="true"/>
 <c:IsImportable i:nil="true"/>
 <c:IsIntersect i:nil="true"/>
 <c:IsMailMergeEnabled i:nil="true"/>
 <c:IsManaged i:nil="true"/>
 <c:IsMappable i:nil="true"/>
 <c:IsReadingPaneEnabled i:nil="true"/>
 <c:IsRenameable i:nil="true"/>
 <c:IsValidForAdvancedFind i:nil="true"/>
 <c:IsValidForQueue i:nil="true"/>
 <c:IsVisibleInMobile>
  <a:CanBeChanged>false</a:CanBeChanged>
  <a:ManagedPropertyLogicalName>canmodifymobilevisibility</a:ManagedPropertyLogicalName>
  <a:Value>false</a:Value>
 </c:IsVisibleInMobile>
 <c:LogicalName>contact</c:LogicalName>
 <c:ManyToManyRelationships i:nil="true"/>
 <c:ManyToOneRelationships i:nil="true"/>
 <c:ObjectTypeCode i:nil="true"/>
 <c:OneToManyRelationships i:nil="true"/>
 <c:OwnershipType i:nil="true"/>
 <c:PrimaryIdAttribute i:nil="true"/>
 <c:PrimaryNameAttribute i:nil="true"/>
 <c:Privileges i:nil="true"/>
 <c:RecurrenceBaseEntityLogicalName i:nil="true"/>
 <c:ReportViewName i:nil="true"/>
 <c:SchemaName i:nil="true"/>
</a:EntityMetadata>

将来のリリースでは、要求していないプロパティの値に null 要素を返さないようにすることでさらなる効率性が達成される可能性もあります。 この XML を解析するためのコードを作成する場合、同じクエリで返される XML を次の XML のみに削除することができることが想定されます。

<a:EntityMetadata>
 <c:MetadataId>608861bc-50a4-4c5f-a02c-21fe1943e2cf</c:MetadataId>
 <c:IsVisibleInMobile>
  <a:CanBeChanged>false</a:CanBeChanged>
  <a:ManagedPropertyLogicalName>canmodifymobilevisibility</a:ManagedPropertyLogicalName>
  <a:Value>false</a:Value>
 </c:IsVisibleInMobile>
 <c:LogicalName>contact</c:LogicalName>
</a:EntityMetadata>

メタデータは階層構造で RetrieveAllEntitiesRequest を使用したときと同じように返されます。 特定の属性または関係にアクセスするには、その一部となるエンティティを返すクエリを作成する必要があります。 特定の属性についてのデータを取得する場合、EntityMetadata.Attributes プロパティを EntityQueryExpression.Properties に含める必要があります。 返されるエンティティ関係で、EntityMetadata プロパティの ManyToManyRelationshipsManyToOneRelationships、または OneToManyRelationships の 1 つまたは複数が含まれている必要があります。

次の例は、要求したエンティティの Attributes プロパティを返します。


//A properties expression to limit the properties to be included with entities
MetadataPropertiesExpression EntityProperties = new MetadataPropertiesExpression()
{
 AllProperties = false
};
EntityProperties.PropertyNames.AddRange(new string[] { "Attributes" });

'A properties expression to limit the properties to be included with entities
Dim EntityProperties As New MetadataPropertiesExpression() With {.AllProperties = False}
EntityProperties.PropertyNames.AddRange(New String() { "Attributes" })

属性メタデータの取得

EntityQueryExpression.AttributeQuery プロパティは、EntityQueryExpressionCriteria および Properties と一致するエンティティに対し返される属性の Criteria および Properties を定義する AttributeQueryExpression を受け入れます。

次の表は、MetadataFilterExpression で使用できない AttributeMetadata プロパティを示します。

Description

DisplayName

OptionSet

Targets

次の例は、返される属性を OptionSet がある属性のみに制限し、これらの属性に対し OptionSet および AttributeType プロパティのみを返します。


//A condition expresson to return optionset attributes
MetadataConditionExpression[] optionsetAttributeTypes = new MetadataConditionExpression[] { 
new MetadataConditionExpression("AttributeType", MetadataConditionOperator.Equals, AttributeTypeCode.Picklist),
new MetadataConditionExpression("AttributeType", MetadataConditionOperator.Equals, AttributeTypeCode.State),
new MetadataConditionExpression("AttributeType", MetadataConditionOperator.Equals, AttributeTypeCode.Status),
new MetadataConditionExpression("AttributeType", MetadataConditionOperator.Equals, AttributeTypeCode.Boolean)
};

//A filter expression to apply the optionsetAttributeTypes condition expression
MetadataFilterExpression AttributeFilter = new MetadataFilterExpression(LogicalOperator.Or);
AttributeFilter.Conditions.AddRange(optionsetAttributeTypes);

//A Properties expression to limit the properties to be included with attributes
MetadataPropertiesExpression AttributeProperties = new MetadataPropertiesExpression() { AllProperties = false };
AttributeProperties.PropertyNames.Add("OptionSet");
AttributeProperties.PropertyNames.Add("AttributeType");

'A condition expresson to return optionset attributes
                  Dim optionsetAttributeTypes() As MetadataConditionExpression =
                      {
                          New MetadataConditionExpression("AttributeType",
                                                          MetadataConditionOperator.Equals,
                                                          AttributeTypeCode.Picklist),
                          New MetadataConditionExpression("AttributeType",
                                                          MetadataConditionOperator.Equals,
                                                          AttributeTypeCode.State),
                          New MetadataConditionExpression("AttributeType",
                                                          MetadataConditionOperator.Equals,
                                                          AttributeTypeCode.Status),
                          New MetadataConditionExpression("AttributeType",
                                                          MetadataConditionOperator.Equals,
                                                          AttributeTypeCode.Boolean)
                      }

'A filter expression to apply the optionsetAttributeTypes condition expression
Dim AttributeFilter As New MetadataFilterExpression(LogicalOperator.Or)
AttributeFilter.Conditions.AddRange(optionsetAttributeTypes)

'A Properties expression to limit the properties to be included with attributes
Dim AttributeProperties As New MetadataPropertiesExpression() With {.AllProperties = False}
AttributeProperties.PropertyNames.Add("OptionSet")
AttributeProperties.PropertyNames.Add("AttributeType")

関連付けのメタデータの取得

EntityQueryExpression.RelationshipQuery プロパティは、EntityQueryExpressionCriteria および Properties と一致するエンティティに必要なエンティティの関連付け Criteria および Properties を指定する RelationshipQueryExpression を受け入れます。

ManyToMany 関連付けまたは OneToMany 関連付けを返すかどうかを指定するには、条件で RelationshipType プロパティを使用します。

次の表は、MetadataFilterExpression で使用できない関連付けメタデータ プロパティを示します。

OneToManyRelationshipMetadata.AssociatedMenuConfiguration

OneToManyRelationshipMetadata.CascadeConfiguration

ManyToManyRelationshipMetadata.Entity1AssociatedMenuConfiguration

ManyToManyRelationshipMetadata.Entity2AssociatedMenuConfiguration

ラベルの取得

最後に、EntityQueryExpression.LabelQuery プロパティは、1 つまたは複数の整数 LCID 値を指定してどのローカライズされたラベルを返すかを決定できる LabelQueryExpression を受け取ります。有効なロケール ID 値については、「Locale ID (LCID) Chart (ロケール ID (LCID) の一覧)」で確認することができます。 組織で複数の言語パックがインストールされている場合は、LabelQuery を指定しないとすべての言語が返されます。

次の例では、ユーザーが使用する言語を表すラベルのみに制限する LabelQueryExpression の定義を示します。


private Guid _userId;
private int _languageCode;

_userId = ((WhoAmIResponse)_service.Execute(new WhoAmIRequest())).UserId;
_languageCode = RetrieveUserUILanguageCode(_userId);

protected int RetrieveUserUILanguageCode(Guid userId)
{
 QueryExpression userSettingsQuery = new QueryExpression("usersettings");
 userSettingsQuery.ColumnSet.AddColumns("uilanguageid", "systemuserid");
 userSettingsQuery.Criteria.AddCondition("systemuserid", ConditionOperator.Equal, userId);
 EntityCollection userSettings = _service.RetrieveMultiple(userSettingsQuery);
 if (userSettings.Entities.Count > 0)
 {
  return (int)userSettings.Entities[0]["uilanguageid"];
 }
 return 0;
}


//A label query expression to limit the labels returned to only those for the user's preferred language
LabelQueryExpression labelQuery = new LabelQueryExpression();
labelQuery.FilterLanguages.Add(_languageCode);

Private _userId As Guid
Private _languageCode As Integer

_userId = (CType(_service.Execute(New WhoAmIRequest()), WhoAmIResponse)).UserId
_languageCode = RetrieveUserUILanguageCode(_userId)

 Protected Function RetrieveUserUILanguageCode(ByVal userId As Guid) As Integer
  Dim userSettingsQuery As New QueryExpression("usersettings")
  userSettingsQuery.ColumnSet.AddColumns("uilanguageid", "systemuserid")
  userSettingsQuery.Criteria.AddCondition("systemuserid", ConditionOperator.Equal, userId)
  Dim userSettings As EntityCollection = _service.RetrieveMultiple(userSettingsQuery)
  If userSettings.Entities.Count > 0 Then
Return CInt(Fix(userSettings.Entities(0)("uilanguageid")))
  End If
  Return 0
 End Function
'A label query expression to limit the labels returned to only those for the user's preferred language
Dim labelQuery As New LabelQueryExpression()
labelQuery.FilterLanguages.Add(_languageCode)

新規または変更済みのメタデータの取得

RetrieveMetadataChangesResponse クラスは要求したデータが含まれている厳密に型指定された EntityMetadataCollection を返します。RetrieveMetadataChangesResponse クラスは、以降の要求でRetrieveMetadataChangesRequest.ClientVersionStamp に渡すことができる ServerVersionStamp 値も含まれています。 値が ClientVersionStamp プロパティに含まれているとき、EntityQueryExpression に一致し、ClientVersionStamp が取得された以降に変更されたデータだけが返されます。 これの唯一の例外は、EntityQueryExpression.PropertiesEntityMetadata.Privileges が含まれている場合です。 特権は ClientVersionStamp に関係なく、常に返されます。 こうすると、アプリケーションで最後にメタデータをクエリした後で関連する重要な変更が発生したかどうかを確認できます。 次に、新しいまたは変更されたメタデータを、アプリケーションで不要なメタデータのダウンロードに伴うパフォーマンスの問題が発生するのを防げるよう、永続メタデータ キャッシュに統合できます。

HasChanged プロパティでは、変更されたメタデータ アイテムの子要素を検出できる方法を提供します。 すべてのメタデータが、メタデータ アイテムの一部として返されるので、OptionMetadata のラベルを変更した場合、含まれる EntityMetadataAttributeMetadataOptionSetMetadata のプロパティが返されます。 ただし、HasChanged プロパティがこれらのメタデータ アイテムを含む場合は false を返します。OptionMetadataHasChanged プロパティのみが true になります。

次の例は EntityQueryExpression を定義し、null に設定されている ClientVersionStamp の要求を実行することにより、最初の要求を作成しています。


//An entity query expression to combine the filter expressions and property expressions for the query.
EntityQueryExpression entityQueryExpression = new EntityQueryExpression()
{

 Criteria = EntityFilter,
 Properties = EntityProperties,
 AttributeQuery = new AttributeQueryExpression()
 {
  Criteria = AttributeFilter,
  Properties = AttributeProperties
 },
 LabelQuery = labelQuery

};

//Retrieve the metadata for the query without a ClientVersionStamp
RetrieveMetadataChangesResponse initialRequest = getMetadataChanges(entityQueryExpression, null, DeletedMetadataFilters.OptionSet);

protected RetrieveMetadataChangesResponse getMetadataChanges(
 EntityQueryExpression entityQueryExpression,
 String clientVersionStamp,
 DeletedMetadataFilters deletedMetadataFilter)
{
 RetrieveMetadataChangesRequest retrieveMetadataChangesRequest = new RetrieveMetadataChangesRequest()
 {
  Query = entityQueryExpression,
  ClientVersionStamp = clientVersionStamp,
  DeletedMetadataFilters = deletedMetadataFilter
 };

 return (RetrieveMetadataChangesResponse)_service.Execute(retrieveMetadataChangesRequest);

}

'An entity query expression to combine the filter expressions and property expressions for the query.
                  Dim entityQueryExpression_Renamed As New EntityQueryExpression() With
                      {
                          .Criteria = EntityFilter,
                          .Properties = EntityProperties,
                          .AttributeQuery = New AttributeQueryExpression() With
                                            {
                                                .Criteria = AttributeFilter,
                                                .Properties = AttributeProperties
                                            },
                          .LabelQuery = labelQuery
                      }

'Retrieve the metadata for the query without a ClientVersionStamp
                  Dim initialRequest As RetrieveMetadataChangesResponse =
                      getMetadataChanges(entityQueryExpression_Renamed, Nothing, DeletedMetadataFilters.OptionSet)

Protected Function getMetadataChanges(ByVal entityQueryExpression_Renamed As EntityQueryExpression,
                                      ByVal clientVersionStamp As String,
                                      ByVal deletedMetadataFilter As DeletedMetadataFilters) As RetrieveMetadataChangesResponse
    Dim retrieveMetadataChangesRequest_Renamed As New RetrieveMetadataChangesRequest() With
        {
            .Query = entityQueryExpression_Renamed,
            .ClientVersionStamp = clientVersionStamp,
            .DeletedMetadataFilters = deletedMetadataFilter
        }

    Return CType(_service.Execute(retrieveMetadataChangesRequest_Renamed), RetrieveMetadataChangesResponse)

End Function

削除されたメタデータに関する情報の取得

RetrieveMetadataChangesResponse.DeletedMetadata プロパティは ClientVersionStampDeletedMetadataFilters プロパティが RetrieveMetadataChangesRequest に設定されている場合 DeletedMetadataCollection を返します。DeletedMetadataCollection には、時間制限内で削除された EntityMetadataAttributeMetadata または RelationshipMetadataBase オブジェクトの MetadataId の値を含みます。 詳細については、「削除されたメタデータの有効期限」を参照してください。

RetrieveMetadataChangesRequest.DeletedMetadataFiltersDeletedMetadataFilters 列挙体を使用して、関心のあるメタデータの種類のみに情報を限定します。DeletedMetadataFilters 列挙体には次のオプションが用意されています。

また DeletedMetadataFilters 列挙体を RetrieveMetadataChangesResponse.DeletedMetadata へのキーとして使用し、RetrieveMetadataChangesResponse.DeletedMetadata プロパティで検索した GUID 値をフィルター処理します。

メタデータ キャッシュの設計を行う場合、削除されたメタデータ アイテムを識別して削除できるよう、アイテムごとに MetadataId を使用することができます。

削除されたメタデータの有効期限

削除されたメタデータ アイテムは、Organization.ExpireSubscriptionsInDays の値により指定されている制限期間中、追跡されます。 既定では、値は 90 日に設定されています。RetrieveMetadataChangesRequest.ClientVersionStamp 値が、最後のメタデータ クエリが有効期限の前のものであることを示している場合、サービスは ExpiredVersionStamp エラー (0x80044352) を表示します。データを取得して更新中に、既存のメタデータ キャッシュを取得しようとするたびにこのエラーが表示され、ClientVersionStamp を使用せずに渡された 2 番目の要求から結果を取得したメタデータ キャッシュの再初期化の準備が行われます。ExpiredVersionStamp エラーは、ExpireSubscriptionsInDays 値の変更などのサーバー上での変更が、削除データの正確な追跡に影響する場合にもスローされます。

次の例は ClientVersionStamp を渡し、ExpiredVersionStamp を取得しています。 エラーが示された場合、キャッシュは null に設定された ClientVersionStamp を使用した新しい要求を渡すことによって再初期化されます。


protected String updateOptionLabelList(EntityQueryExpression entityQueryExpression, String clientVersionStamp)
{
 //Retrieve metadata changes and add them to the cache
 RetrieveMetadataChangesResponse updateResponse;
 try
 {
  updateResponse = getMetadataChanges(entityQueryExpression, clientVersionStamp, DeletedMetadataFilters.OptionSet);
  addOptionLabelsToCache(updateResponse.EntityMetadata, true);
  removeOptionLabelsFromCache(updateResponse.DeletedMetadata, true);

 }
 catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault> ex)
 {
  // Check for ErrorCodes.ExpiredVersionStamp (0x80044352)
  // Will occur when the timestamp exceeds the Organization.ExpireSubscriptionsInDays value, which is 90 by default.
  if (ex.Detail.ErrorCode == unchecked((int)0x80044352))
  {
   //reinitialize cache
   _optionLabelList.Clear();

   updateResponse = getMetadataChanges(entityQueryExpression, null, DeletedMetadataFilters.OptionSet);
   //Add them to the cache and display the changes
   addOptionLabelsToCache(updateResponse.EntityMetadata, true);

  }
  else
  {
   throw ex;
  }

 }
 return updateResponse.ServerVersionStamp;
}

Protected Function updateOptionLabelList(ByVal entityQueryExpression_Renamed As EntityQueryExpression,
                                         ByVal clientVersionStamp As String) As String
    'Retrieve metadata changes and add them to the cache
    Dim updateResponse As RetrieveMetadataChangesResponse
    Try
        updateResponse = getMetadataChanges(entityQueryExpression_Renamed, clientVersionStamp, DeletedMetadataFilters.OptionSet)
        addOptionLabelsToCache(updateResponse.EntityMetadata, True)
        removeOptionLabelsFromCache(updateResponse.DeletedMetadata, True)

    Catch ex As FaultException(Of Microsoft.Xrm.Sdk.OrganizationServiceFault)
        ' Check for ErrorCodes.ExpiredVersionStamp (0x80044352)
        ' Will occur when the timestamp exceeds the Organization.ExpireSubscriptionsInDays value, which is 90 by default.
        'INSTANT VB TODO TASK: There is no VB equivalent to 'unchecked' in this context:
        If ex.Detail.ErrorCode = CInt(&amp;H80044352) Then
            'reinitialize cache
            _optionLabelList.Clear()

            updateResponse = getMetadataChanges(entityQueryExpression_Renamed, Nothing, DeletedMetadataFilters.OptionSet)
            'Add them to the cache and display the changes
            addOptionLabelsToCache(updateResponse.EntityMetadata, True)

        Else
            Throw ex
        End If

    End Try
    Return updateResponse.ServerVersionStamp
End Function

削除されたメタデータを取得するときのパフォーマンス

メタデータ アイテムを削除すると、Microsoft Dynamics 365 メタデータ キャッシュではなくデータベースに保存されます。 削除されたメタデータが MetadataId とメタデータ アイテムの種類のみに制限されていても、データベースへのアクセスは変更をクエリするだけの場合よりもより多くのサーバー リソースが必要な操作です。

関連項目

サーバー上の Microsoft Dynamics 365 の拡張
Microsoft Dynamics 365 サービスをオフラインで使用する
サンプル: メタデータのクエリと変更の検出
Dynamics 365 メタデータと共に組織サービスを使用する
エンティティ メタデータのカスタマイズ
エンティティ属性メタデータのカスタマイズ
エンティティ関係メタデータをカスタマイズする
JavaScript を使用したメタデータのクエリ

Microsoft Dynamics 365

© 2017 Microsoft. All rights reserved. 著作権