Freigeben über


Abrufen und Erkennen von Änderungen bei Metadaten

 

Veröffentlicht: Januar 2017

Gilt für: Dynamics 365 (online), Dynamics 365 (on-premises), Dynamics CRM 2016, Dynamics CRM Online

Die Klassen im Microsoft.Xrm.Sdk.Metadata.Query-Namespace und die RetrieveMetadataChangesResponse- und RetrieveMetadataChangesRequest-Klassen erlauben Ihnen, effiziente Metadatenabfragen aufzubauen und Änderungen an den Metadaten, die im Laufe der Zeit auftreten, zu erfassen.

Alle Codebeispiele, auf die in diesem Dokument verwiesen wird, finden sich in Beispiel: Abfragen von Metadaten und Erkennen von Änderungen.

Der technische Artikel Metadaten mithilfe von JavaScript abfragen bietet eine JavaScript-Bibliothek, um die Objekte und Nachrichten in clientseitigem Code zu verwenden.

In diesem Thema

Strategien für die Verwendung von Metadaten

Rufen Sie nur die Metadaten ab, die Sie benötigen.

Abrufen von neuen oder geänderten Metadaten

Abrufen von Informationen zu gelöschten Metadaten

Strategien für die Verwendung von Metadaten

Mithilfe von Metadaten können Sie Anwendungen erstellen, die sich anpassen, während das Microsoft Dynamics 365-Datenmodell sich ändert. Metadaten sind für die folgenden Typen von Anwendungen wichtig:

  • UI für-Client-Anwendungen

  • Integrationstools, die Dynamics 365-Daten externen Systemen zuordnen müssen

  • Entwicklungstools

Bei Verwenden der Klassen im Microsoft.Xrm.Sdk.Metadata.Query-Namespace können Sie Entwürfe implementieren, die irgendwo zwischen einer Abfrage mit geringem Umfang und einem permanenten Metadatencache liegen.

Einfache Abfrage

Ein Beispiel für eine einfache Abfrage ist es, wenn Sie eine benutzerdefinierte Webressourcen-Benutzeroberfläche haben, die ein Auswahlsteuerelement bereitstellt, um die aktuellen Optionen in einem Microsoft Dynamics 365-Optionssatzattribut (Auswahllistenattribut) anzuzeigen. Sie möchten diese Optionen nicht hartcodiert festlegen, da Sie diesen Code aktualisieren müssten, wenn die verfügbaren Optionen jemals geändert werden. Stattdessen können Sie eine Abfrage erstellen, um nur diese Optionswerte und Beschriftungen aus den Metadaten abzurufen.

Sie müssen diese Daten nicht zwischenspeichern, da Sie die Microsoft.Xrm.Sdk.Metadata.Query-Klassen verwenden können, um diese Daten direkt aus dem Microsoft Dynamics 365-Anwendungscache abzurufen.

Dauerhafter Metadatencache

Wenn Sie eine Anwendung haben, die arbeiten können muss, während sie vom Microsoft Dynamics 365 getrennt ist, oder die durch eine beschränkte Netzwerk-Bandbreite zwischen dem Client und dem Server leicht beeinträchtigt wird, wie etwa eine mobile Anwendung, müssen Sie einen dauerhaften Metadatencache implementieren.

Mit einem dauerhaften Metadatencache muss Ihre Anwendung alle notwendigen Metadaten abfragen, wenn sie zum ersten Mal eine Verbindung herstellen. Anschließend speichern Sie diese Daten in der Anwendung. Das nächste Mal, wenn die Anwendung eine Verbindung mit dem Server herstellt, können Sie einfach Unterschied abfragen, was sehr viel weniger zu übertragende Daten bedeuten sollte, und dann die Änderungen mit den Metadatencache zusammenführen, wenn die Anwendung geladen wird.

Wie häufig Sie nach Metadatenänderungen abfragen sollten, hängt von der erwarteten Volatillität der Metadaten für die Anwendung ab, und wie lange die Anwendung weiterhin ausgeführt wird. Es ist kein Ereignis verfügbar, das Sie verwenden können, um zu ermitteln, wann Metadatenänderungen eintreten. Es gibt eine Begrenzung für die Anzahl der Tage, die Metadatenänderungen gespeichert werden, und eine Anforderungen von Änderungen, die jenseits dieser Beschränkung auftritt, erfordert eine vollständige Reinitialisierung des Metadatencache. Weitere Informationen finden Sie unter Ablauf gelöschter Metadaten.

Sind keine Änderungen vorhanden, sollte die Abfrage schnell reagieren, und es sind keine Daten vorhanden, die zurückzugeben sind. Falls jedoch Änderungen vorhanden sind, insbesondere wenn es gelöschte Metadatenelemente gibt, die aus dem Cache entfernt werden müssen, können Sie damit rechnen, dass die Anforderung einige Zeit in Anspruch nehmen kann.Weitere Informationen:Leistung beim Abrufen gelöschter Metadaten

Rufen Sie nur die Metadaten ab, die Sie benötigen.

Metadaten werden häufig abgerufen oder synchronisiert, wenn eine Anwendung gestartet wird und sich auf die Zeit auswirken kann, die die Anwendung zum Laden benötigt. Dies gilt besonders für mobile Anwendungen, die zum ersten Mal Metadaten abrufen. Nur die Metadaten abzurufen, die Sie benötigen, ist sehr wichtig, um eine Anwendung zu erstellen, die gute Leistung bringt.

Die EntityQueryExpression-Klasse bietet eine Struktur, die mit der QueryExpression-Klasse konsistent ist, die Sie verwenden, um komplexe Abfragen zu erstellen, um Entitätsdaten abzurufen. Anders als die RetrieveAllEntitiesRequest, RetrieveEntityRequest, RetrieveAttributeRequest, oder RetrieveRelationshipRequest-Klassen enthält RetrieveMetadataChangesRequest einen Query-Parameter, der eine EntityQueryExpression-Instanz akzeptiert, die Sie verwenden können, um spezifische Kriterien für die zurückzugebenden Daten festzulegen, zusätzlich zu den Eigenschaften, die Sie wünschen. Sie können RetrieveMetadataChangesRequest verwenden, um den ganzen Satz von Metadaten zurückzugeben, die Sie erhalten, wenn Sie RetrieveAllEntitiesRequest verwenden, oder nur eine Beschriftung für ein bestimmtes Attribut.

Angeben der Filterkriterien

Die EntityQueryExpression.Criteria-Eigenschaft akzeptiert einen MetadataFilterExpression, der eine Sammlung von MetadataConditionExpression-Objekte enthält, die das Festlegen von Bedingungen zum Filtern von Entitätseigenschaften auf der Grundlage ihres Wertes zulassen. Diese Anforderungen verwenden einen MetadataConditionOperator, der folgende Operatoren zulässt:

Der MetadataFilterExpression enthält außerdem einen LogicalOperator, um darzustellen, ob And oder Or-Logik angewendet wird, wenn Sie die Bedingungen auswerten.

Nicht alle Eigenschaften können als Filterkriterien verwendet werden. Nur Eigenschaften, die einfache Datentypen, Aufzählen, BooleanManagedProperty oder AttributeRequiredLevelManagedProperty-Typen darstellen, können in einer MetadataFilterExpression verwendet werden. Wenn eine BooleanManagedProperty oder AttributeRequiredLevelManagedProperty angegeben ist, kann nur die Eigenschaft Value ausgewertet werden.

In der folgenden Tabelle werden EntityMetadata-Eigenschaften aufgeführt, die in nicht in einem MetadataFilterExpression verwendet werden können:

Attributes

Description

DisplayCollectionName

DisplayName

ManyToManyRelationships

ManyToOneRelationships

OneToManyRelationships

Privileges

Im folgenden Beispiel wird ein MetadataFilterExpression angezeigt, der einen Satz von nicht sich überschneiden Entitäten im Besitz des Benutzers zurückgibt, die nicht in einer Liste von Entitäten enthalten sind, die ausgeschlossen sind:



     // 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)

Erstellen der Eigenschaften, die Sie wünschen

Die Properties-Eigenschaft akzeptiert einen MetadataPropertiesExpression. Sie können MetadataPropertiesExpression.AllProperties zu true festlegen, wenn Sie alle Eigneshcaften zurückgeben möchten oder eine Sammlung von Zeichenfolgen für MetadataPropertiesExpression.PropertyNames berietstellen möchten, um festzulegen, welche Eigenschaften Sie in die Ergebnisse einschlie'en möchten.

Die zurückgegebenen stark typisierten Objekte enthalten alle Eigenschaften, aber nur die, die Sie benötigen, enthalten Daten. Alle anderen Eigenschaften sind Null, mit den folgenden wenigen Ausnahmen: jedes Metadatenelement enthält die MetadataId ,LogicalName und HasChanged-Werte, wenn sie für dieses Element vorhanden sind. Sie müssen sie nicht in den Properties angeben, die Sie benötigen.

Wenn Sie nicht verwalteten Code verwenden, und die responseXML analysieren, das von der XMLHttpRequest zurückgegeben wurde, erhalten Sie Elemente für jede Eigenschaft, aber nur die, die Sie benötigen, enthalten Daten. Das folgende XML zeigt die Kontaktentitätsmetadaten-XML, die zurückgegeben wird, wenn IsVisibleInMobile die einzige angeforderte Eigenschaft ist.

<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>

In einer zukünftigen Version wird möglicherweise mehr Effizienz erreicht, indem Elementen mit leeren Werten für Eigenschaften , die nicht angefordert wurden, nicht zurückgegeben werden. Wenn Sie Code schreiben, um diese XML zu analysieren, sollten Sie erwarten, dass die XML-Datei, die für dieselbe Abfrage zurückgegeben wurde, zu der folgenden XML-Datei reduziert werden könnte.

<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>

Metadaten werden in einer Baumstruktur zurückgegeben, wie sie die RetrieveAllEntitiesRequest verwendet. Um auf ein ein bestimmtes Attribut oder eine Beziehung zuzugreifen, müssen Sie eine Abfrage erstellen, die die Entität zurückgibt, von der sie ein Teil ist. Wenn Sie Daten über ein bestimmtes Attribut abrufen möchten, müssen Sie die EntityMetadata.Attributes-Eigenschaft in Ihre EntityQueryExpression.Properties einschließen. Damit Entitätsbeziehungen zurückgegeben werden, müssen Sie mindestens eine der folgenden Eigenschaften EntityMetadata enthalten: ManyToManyRelationships, ManyToOneRelationships oder OneToManyRelationships.

Das folgende Bespiel wird die Attributes-Eigenschaft für die angeforderte Entitäten zurückgeben:


//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" })

Attribut-Metadaten abrufen

Die EntityQueryExpression.AttributeQuery-Eigenschaft übernimmt eine AttributeQueryExpression, die Criteria und Properties für Attribute übernimmt, die für die Entitäten zurückgegeben werden sollen, die mit EntityQueryExpressionCriteria und Properties übereinstimmen.

In der folgenden Tabelle werden AttributeMetadata-Eigenschaften aufgeführt, die nicht in einer MetadataFilterExpression verwendet werden können.

Description

DisplayName

OptionSet

Targets

Das folgende Bespiel beschränkt die zurückgegebenen Attribute nur auf solche, die ein OptionSet haben und nur die OptionSet- und AttributeType-Eigenschaften für diese Attribute zurückgegeben:


//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")

Beziehungsmetadaten abrufen

Die EntityQueryExpression.RelationshipQuery-Eigenschaft übernimmt eine RelationshipQueryExpression, um die Entitätsbeziehung Criteria und Properties anzugeben, die Sie für die Entitäten wünschen, die mit EntityQueryExpressionCriteria und Properties übereinstimmen.

Verwenden Sie die Eigenschaft RelationshipType in den Kriterien, um anzugeben, dass Sie OneToMany-Beziehungen oder ManyToMany-Beziehungen zurückgeben möchten.

In der folgenden Tabelle werden Beziehungsmetadateneigenschaften aufgeführt, die in einer MetadataFilterExpression nicht verwendet werden können.

OneToManyRelationshipMetadata.AssociatedMenuConfiguration

OneToManyRelationshipMetadata.CascadeConfiguration

ManyToManyRelationshipMetadata.Entity1AssociatedMenuConfiguration

ManyToManyRelationshipMetadata.Entity2AssociatedMenuConfiguration

Abrufen von Beschriftungen

Schließlich akzeptiert die EntityQueryExpression.LabelQuery-Eigenschaft eine LabelQueryExpression, mit der Sie einen oder mehrere ganzzahlige LCID-Werte angeben können, um zu bestimmen, welche lokalisierten Beschriftungen zurückgegeben werden sollen.Gültige Gebietsschema-ID-Werte finden Sie unter Gebietsschema-ID-Diagramm (LCID). Wenn eine Organisation viele Sprachpakete installiert hat, werden die Beschriftungen für alle Sprachen zurückgegeben, es sei denn, Sie legen eine LabelQuery fest.

Das folgende Bespiel definiert eine LabelQueryExpression, die Beschriftungen auf solche beschränkt, die die bevorzugte Sprache des Benutzers darstellen.


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)

Abrufen von neuen oder geänderten Metadaten

Die Klasse RetrieveMetadataChangesResponse gibt eine stark typisierte EntityMetadataCollection zurück, die die nachgefragten Daten enthält. Die RetrieveMetadataChangesResponse-Klasse bietet auch einen ServerVersionStamp-Wert, den Sie an die RetrieveMetadataChangesRequest.ClientVersionStamp-Eigenschaft in späteren Abfragen übergeben können. Wenn ein Wert für die ClientVersionStamp-Eigenschaft eingeschlossen wird, werden nur Daten zurückgegeben, die der EntityQueryExpression entsprechen, und die sich geändert haben, seit der ClientVersionStamp abgerufen wurde. Die einzige Ausnahme davon ist, wenn EntityQueryExpression.Properties die EntityMetadata.Privileges enthält. Rechte werden immer zurückgegeben, unabhängig vom ClientVersionStamp. Dadurch kann die Anwendung bestimmen, ob wichtige Änderungen eingetreten sind, seit Sie zuletzt die Metadaten abgerufen haben. Sie können dann neue oder geänderte Metadaten im dauerhaften Metadatencache zusammenführen, sodass die Anwendung in der Lage ist, Leistungsprobleme durch das Herunterladen von Metadaten zu vermeiden, die möglicherweise nicht erforderlich sind.

Die Eigenschaft HasChanged bietet eine Möglichkeit, festzustellen, welche untergeordneten Elemente in einem Metadatenelement sich geändert haben. Da alle Metadaten im Rahmen des Metadatenelements zurückgegeben werden, wenn die Beschriftung eines OptionMetadata sich geändert hat, werden die enthaltende EntityMetadata, AttributeMetadata und OptionSetMetadata-Eigenschaft zurückgegeben. Die Eigenschaft HasChanged ist jedoch falsch für solche, die Metadatenelemente enthalten. Nur die Eigenschaft OptionMetadataHasChanged ist wahr.

Das folgende Beispiel enthält eine anfängliche Abfrage durch Definieren einer EntityQueryExpression und Durchführen einer Abfrage, bei der ClientVersionStamp auf Null gesetzt ist.


//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

Abrufen von Informationen zu gelöschten Metadaten

Die RetrieveMetadataChangesResponse.DeletedMetadata-Eigenschaft gibt eine DeletedMetadataCollection zurück, wenn die Eienschaften ClientVersionStamp und DeletedMetadataFilters in der RetrieveMetadataChangesRequest festgelegt sind. Die DeletedMetadataCollection enthält die MetadataId-Werte von EntityMetadata, AttributeMetadata or RelationshipMetadataBase-Objekten, die in einem Zeitlimit vom System gelöscht wurden. Weitere Informationen finden Sie unter Ablauf gelöschter Metadaten.

Verwenden Sie die DeletedMetadataFilters-Enumeration mit der RetrieveMetadataChangesRequest.DeletedMetadataFilters, um die Informationen auf die Typen von Metadaten zu beschränken, an denen Sie interessiert sind. Die DeletedMetadataFilters-Aufzählung bietet folgende Optionen:

Sie verwenden die DeletedMetadataFilters-Aufzählung auch als Schlüssel für RetrieveMetadataChangesResponse.DeletedMetadata um die GUID-Werte zu filtern, die in der RetrieveMetadataChangesResponse.DeletedMetadata-Eigenschaft gefunden werden.

Wenn Sie einen Metadatencache entwickeln, verwenden Sie die MetadataId für jedes Element, sodass Sie die gelöschten Metadatenelemente identifizieren und entfernen können.

Ablauf gelöschter Metadaten

Metadatenelemente, der gelöscht wurden, werden für einen beschränkten Zeitraum nachverfolgt, der durch den Organization.ExpireSubscriptionsInDays-Wert angegeben wird. Der Standardwert ist 90 Tage. Wenn der RetrieveMetadataChangesRequest.ClientVersionStamp-Wert anzeigt, dass die letzt Metadatenabfrage vor dem Ablaufdatum lag, wirft der Service einen ExpiredVersionStamp-Fehler (0x80044352) aus. Wenn Sie Daten abrufen, um einen vorhandenen Metadatencache zu aktualisieren, sollten Sie immer versuchen, diesen Fehler abzufangen und bereit sein, den Metatadatencache mit den Ergebnissen einer zweiten Abfrage zu re-initialisieren, die ohne ClientVersionStamp übergeben wurde. Der Fehler wird ExpiredVersionStamp wird auch ausgegeben, wenn Änderungen auf dem Server, wie Änderungen am ExpireSubscriptionsInDays-Wert, sich auf die exakte Nachverfolgung der gelöschte Metadaten auswirken.

Das folgenden Beispiel übergibt einen ClientVersionStamp und fängt den ExpiredVersionStamp ab. Wenn der Fehler abgefangen wird, wird der Cache reintialisert, indem eine neue Abfrage mit dem ClientVersionStamp-Set auf null eingereicht wird.


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

Leistung beim Abrufen gelöschter Metadaten

Wenn ein Metadatenelement gelöscht wird, wird es in der Datenbank gespeichert, und nicht im Microsoft Dynamics 365-Metadatencache. Obwohl die gelöschte Metadaten nur auf die MetadataId und den Typ des Metadatenelements beschränkt sind, ist der Zugriff auf die Datenbank ein Vorgang, der mehr Serverressourcen erfordert als nur die Abfrage nach Änderungen.

Siehe auch

Microsoft Dynamics 365 auf dem Server erweitern
Offline-Verwendung der Microsoft Dynamics 365-Services
Beispiel: Abfragen von Metadaten und Erkennen von Änderungen
Verwenden des Organisationsdienstes mit Dynamics 365-Metadaten
Anpassen von Entitätsmetadaten
Anpassen von Entitätsattributmetadaten
Anpassen von Entitätsbeziehungsmetadaten
Abfragemetadaten mit JavaScript

Microsoft Dynamics 365

© 2017 Microsoft. Alle Rechte vorbehalten. Copyright