Del via


Hent og registrer ændringer af metadata

 

Udgivet: januar 2017

Gælder for: Dynamics 365 (online), Dynamics 365 (on-premises), Dynamics CRM 2016, Dynamics CRM Online

Med klasserne i navneområdet Microsoft.Xrm.Sdk.Metadata.Query og klasserne RetrieveMetadataChangesRequest og RetrieveMetadataChangesResponse kan du opbygge effektive forespørgsler på metadata og registrere ændringer af metadata, efterhånden som de indtræffer med tiden.

Alle de kodeeksempler, der refereres til i dette dokument, findes under Eksempel: Forespørg på metadata, og registrer ændringer.

Den tekniske artikel Forespørg på metadata ved hjælp af JavaScript indeholder et JavaScript-bibliotek, så objekterne og meddelelserne kan bruges i kode, der bruges af klienten.

Dette emne indeholder

Strategier for brug af metadata

Hent kun de metadata, du har brug for

Hent nye eller ændrede metadata

Hent oplysninger om slettede metadata

Strategier for brug af metadata

Med metadata, kan du oprette programmer, som tilpasses, efterhånden som Microsoft Dynamics 365-datamodellen ændres. Metadata er vigtige for følgende typer af programmet:

  • Brugergrænseflade til klientprogrammer

  • Integrationsværktøjer, der skal knytte Dynamics 365-data til eksterne systemer

  • Udviklingsværktøjer

Med klasserne i navneområdet Microsoft.Xrm.Sdk.Metadata.Query kan du implementere design, der skal findes et sted mellem en let forespørgsel og en fast metadatacache.

Let forespørgsel

Et eksempel på en let forespørgsel er, når du har en brugergrænseflade til en brugerdefineret webressource med et valgkontrolelement, der kan vise de aktuelle indstillinger i en attribut for en Microsoft Dynamics 365-grupperet indstilling (valgliste). Du vil ikke "hardcode" disse indstillinger, da du ville skulle opdatere koden, hvis de tilgængelige indstillinger på et tidspunkt ændres. I stedet kan du oprette en forespørgsel for blot at hente disse indstillingsværdier og -etiketter i metadataene.

Du behøver ikke at cachelagre disse data, fordi du kan bruge Microsoft.Xrm.Sdk.Metadata.Query-klasserne til at hente dataene direkte fra Microsoft Dynamics 365-programcachen.

Fast metadatacache

Når du har et program, der skal være i stand til at arbejde offline fra Microsoft Dynamics 365-serveren, eller som er følsomt over for begrænset netværksbåndbredde mellem klienten og serveren, f.eks et mobilprogram, er det en god ide at implementere en fast metadatacache.

Med en fast metadatacache skal programmet forespørge på alle nødvendige metadata, første gang der oprettes forbindelse. Derefter skal du gemme dataene i programmet. Næste gang programmet opretter forbindelse til serveren, kan du hente lige netop forskellen siden din sidste forespørgsel, hvilket bør betyde langt færre data at overføre, og derefter flette ændringerne i din metadatacache, når programmet indlæses.

Hvor ofte du bør undersøge, om der er ændringer af metadata, afhænger af den forventede ustabilitet af metadata til programmet, og hvor lang tid programmet fortsat vil køre. Der er ingen hændelse, som du kan bruge til at registrere, når der sker metadataændringer. Der er en grænse for antallet af dage, hvor slettede ændringer af metadata gemmes, og en anmodning om ændringer, der opstår uden for denne grænse, kræver en fuld reinitialisering af metadatacachen. Du kan finde flere oplysninger i Udløb af slettede metadata.

Når der ikke er nogen ændringer, skal forespørgslen reagere hurtigt, og der vil være nogen data at sende tilbage. Men hvis der er ændringer, især hvis der er slettede metadataelementer, der skal fjernes fra cachen, kan du forvente, at anmodningen kan tage ekstra tid at afslutte.Flere oplysninger:Ydeevne, når der hentes slettede metadata

Hent kun de metadata, du har brug for

Metadata hentes eller synkroniseres ofte, når et program startes, og kan påvirke den tid, det tager programmet at indlæse. Dette er især tilfældet for mobilprogrammer, der henter metadata for første gang. Det er meget vigtigt kun at hente de metadata, du har brug for, når du vil oprette et program, der kører godt.

Klassen EntityQueryExpression giver en struktur, der stemmer overens med den QueryExpression-klasse, du bruger til at oprette komplekse forespørgsler for at hente objektdata. I modsætning til klasserne RetrieveAllEntitiesRequest, RetrieveEntityRequest, RetrieveAttributeRequest eller RetrieveRelationshipRequest indeholder RetrieveMetadataChangesRequest en Query-parameter, der accepterer en forekomst af EntityQueryExpression, som du kan bruge til at angive specifikke kriterier for de data, der skal returneres, ud over de egenskaber, du ønsker. Du kan bruge RetrieveMetadataChangesRequest til at returnere det fuldstændige sæt af metadata, som du får ved hjælp af RetrieveAllEntitiesRequest, eller blot en etiket til en bestemt attribut.

Angiv dine filterkriterier

Egenskaben EntityQueryExpression.Criteria accepterer en MetadataFilterExpression, der indeholder en samling af MetadataConditionExpression-objekter, der giver mulighed for at definere betingelser for filtrering af egenskaber for objekter, der er baseret på deres værdi. Disse betingelser bruger en MetadataConditionOperator, der giver mulighed for brug af følgende operatorer:

MetadataFilterExpression indeholder også en LogicalOperator, som du kan bruge til at angive, om du vil anvende And eller Or-logik, når du evaluerer betingelserne.

Ikke alle egenskaber kan bruges som filterkriterier. Kun egenskaber, der repræsenterer simple datatyper, optællinger, BooleanManagedProperty- eller AttributeRequiredLevelManagedProperty-typer kan bruges i en MetadataFilterExpression. Når en BooleanManagedProperty eller AttributeRequiredLevelManagedProperty angives, kun er det kun egenskaben Value, som evalueres.

Følgende tabel indeholder EntityMetadata-egenskaber, der ikke kan bruges i et MetadataFilterExpression:

Attributes

Description

DisplayCollectionName

DisplayName

ManyToManyRelationships

ManyToOneRelationships

OneToManyRelationships

Privileges

Følgende eksempel viser et MetadataFilterExpression, der returnerer et sæt ikke-overlappende brugerejede objekter, der ikke er omfattet af en liste over objekter, der skal udelukkes:



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

Angiv de ønskede egenskaber

Egenskaben Properties accepterer et MetadataPropertiesExpression. Du kan indstille MetadataPropertiesExpression.AllProperties til true, hvis du vil returnere alle egenskaberne, eller du kan angive en samling strenge til MetadataPropertiesExpression.PropertyNames for at definere, hvilke egenskaber du vil medtage i resultaterne.

De typesikre returnerede objekter omfatter alle egenskaber, men kun dem, du anmoder om, indeholder data. Andre egenskaber er null, med følgende få undtagelser: hvert element af metadata omfatter værdierne MetadataId, LogicalName og HasChanged, hvis de findes for det pågældende element. Du behøver ikke at angive dem i den Properties, du anmoder om.

Hvis du ikke bruger administreret kode og faktisk fortolker den responseXML, der blev returneret fra XMLHttpRequest, får du elementer for hver egenskab, men kun dem, du anmoder om, indeholder data. Følgende XML viser kontaktobjektets metadata-xml, som returneres, når IsVisibleInMobile er den eneste egenskab, der er anmodet om.

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

Der kan opnås effektivitetsfordele i fremtidige versioner ved ikke at returnere elementer med null-værdier for egenskaber, der ikke blev anmodet om. Hvis du skriver kode for at fortolke denne XML, kan du forvente, at den XML, der returneres for den samme forespørgsel, evt. er reduceret til kun følgende 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>

Metadata returneres i en hierarkisk struktur, på samme måde som med RetrieveAllEntitiesRequest. For at få adgang til en bestemt attribut eller relation skal du oprette en forespørgsel, der returnerer det objekt, de er en del af. Hvis du vil hente data om en bestemt attribut, skal du medtage EntityMetadata.Attributes-egenskaben i dine EntityQueryExpression.Properties. Når objektrelationerne skal returneres, skal du medtage en eller flere af følgende EntityMetadata-egenskaber: ManyToManyRelationships, ManyToOneRelationships eller OneToManyRelationships.

Følgende eksempel returnerer egenskaben Attributes for de objekter, der anmodes om:


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

Hent attributmetadata

Egenskaben EntityQueryExpression.AttributeQuery accepterer en AttributeQueryExpression, der definerer Criteria og Properties for attributter, der sal returneres for de objekter, der svarer til EntityQueryExpressionCriteria og Properties.

Følgende tabel indeholder AttributeMetadata-egenskaber, der ikke kan bruges i et MetadataFilterExpression

Description

DisplayName

OptionSet

Targets

Følgende eksempel begrænser attributter, der er returneres, til dem, der har en OptionSet, og returnerer kun egenskaberne OptionSet og AttributeType for disse attributter:


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

Hent metadata for relation

Egenskaben EntityQueryExpression.RelationshipQuery accepterer et RelationshipQueryExpression for at angive den objektrelation mellem Criteria og Properties, som du vil bruge til de objekter, der svarer til EntityQueryExpressionCriteria og Properties.

Brug egenskaben RelationshipType i dine kriterier for at angive, om du vil returnere ManyToMany eller OneToMany relationer.

Følgende tabel indeholder egenskaber for relationsmetadata, der ikke kan bruges i et MetadataFilterExpression:

OneToManyRelationshipMetadata.AssociatedMenuConfiguration

OneToManyRelationshipMetadata.CascadeConfiguration

ManyToManyRelationshipMetadata.Entity1AssociatedMenuConfiguration

ManyToManyRelationshipMetadata.Entity2AssociatedMenuConfiguration

Hent etiketter

Endelig accepterer egenskaben EntityQueryExpression.LabelQuery et LabelQueryExpression, som gør det muligt for dig at angive en eller flere LCID-heltalsværdier for at bestemme, hvilke oversatte etiketter der skal returneres.Du kan finde gyldige landestandard-id'er på Oversigt over landestandard-id'er. Hvis en organisation har mange installerede sprogpakker, returneres etiketter for alle sprog, medmindre du angiver en LabelQuery.

I følgende eksempel defineres et LabelQueryExpression, der begrænser etiketter til dem, der repræsenterer brugernes foretrukne sprog.


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)

Hent nye eller ændrede metadata

Klassen RetrieveMetadataChangesResponse returnerer en typesikker EntityMetadataCollection, der indeholder de ønskede data. Klassen RetrieveMetadataChangesResponse indeholder også en ServerVersionStamp-værdi, som du kan overføre til egenskaben RetrieveMetadataChangesRequest.ClientVersionStamp i senere anmodninger. Når en værdi er inkluderet for egenskaben ClientVersionStamp, returneres kun de data, der svarer til EntityQueryExpression og er blevet ændret siden ClientVersionStamp blev hentet. Den eneste undtagelse er, når EntityQueryExpression.Properties inkluderer EntityMetadata.Privileges. Rettigheder returneres altid uanset ClientVersionStamp. På denne måde kan dit program fastslå, om der er opstået vigtige ændringer, der interesserer dig, siden du sidst forespurgte på metadataene. Derefter kan du flette eventuelle nye eller ændrede metadata sammen med din faste metadatacache, så programmet vil kunne undgå problemerne med at downloade metadata, der ikke er nødvendige.

Egenskaben HasChanged giver mulighed for at registrere, hvilke underordnede elementer i et metadataelementet der er ændret. Alle metadata returneres som en del af indholdsmetadataelementet, så når etiketten for en OptionMetadata ændres, returneres indholdsegenskaberne for EntityMetadata, AttributeMetadata og OptionSetMetadata. Men egenskaben HasChanged er false for de pågældende indholdsmetadataelementer. Kun egenskaben OptionMetadata.HasChanged er sand.

I følgende eksempel foretages en indledende anmodning ved at definere et EntityQueryExpression og udføre en anmodning med ClientVersionStamp indstillet til null.


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

Hent oplysninger om slettede metadata

Egenskaben RetrieveMetadataChangesResponse.DeletedMetadata returnerer en DeletedMetadataCollection, når egenskaberne ClientVersionStamp og DeletedMetadataFilters er indstillet for RetrieveMetadataChangesRequest.DeletedMetadataCollection indeholder MetadataId-værdierne for eventuelle EntityMetadata-, AttributeMetadata- eller RelationshipMetadataBase-objekter, der er blevet slettet fra systemet inden for et afgrænset tidsrum. Du kan finde flere oplysninger under Udløb af slettede metadata.

Brug optællingen DeletedMetadataFilters med RetrieveMetadataChangesRequest.DeletedMetadataFilters for at begrænse oplysningerne til kun de typer metadata, du er interesseret i. Optællingen DeletedMetadataFilters indeholder følgende indstillinger:

Du skal også bruge DeletedMetadataFilters-optælling som en nøgle til RetrieveMetadataChangesResponse.DeletedMetadata for at filtrere de GUID-værdier, der findes i egenskaben RetrieveMetadataChangesResponse.DeletedMetadata.

Når du designer en metadatacache, skal du bruge MetadataId til hvert element, så du kan identificere slettede metadataelementer og fjerne dem.

Udløb af slettede metadata

Metadataelementer, der slettes, spores i et begrænset tidsrum, der angives af værdien Organization.ExpireSubscriptionsInDays. Denne værdi er som standard 90 dage. Hvis RetrieveMetadataChangesRequest.ClientVersionStamp-værdien angiver, at den sidste forespørgsel på metadata blev foretaget før udløbsdatoen, udløser servicen en ExpiredVersionStamp-fejl (0x80044352). Når du henter data for at opdatere en eksisterende metadatacache, bør du altid forsøge at fange denne fejl og være forberedt på at geninitialisere din metadatacache med resultaterne fra en anden anmodning, som er sendt uden ClientVersionStamp.ExpiredVersionStamp-fejlen opstår også, når ændringer på serveren, såsom ændringer af ExpireSubscriptionsInDays-værdien, påvirker den præcise registrering af slettede metadata.

Følgende eksempel sender et ClientVersionStamp og fanger ExpiredVersionStamp. Hvis fejlen fanges, initialiseres cachen igen, ved at der sendes en ny anmodning med ClientVersionStamp indstillet til null.


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

Ydeevne, når der hentes slettede metadata

Når et metadataelement slettes, gemmes det i databasen og ikke i Microsoft Dynamics 365-metadatacachen. Selvom de slettede metadata er begrænset til blot MetadataId og typen af metadataelement, vil adgang til databasen kræver flere serverressourcer end blot forespørgsler om ændringer.

Se også

Udvide Microsoft Dynamics 365 på serveren
Offlinebrug af Microsoft Dynamics 365-tjenesterne
Eksempel: Forespørg på metadata, og registrer ændringer
Bruge organisationstjenesten med Dynamics 365-metadata
Tilpasse objektets metadata
Tilpasse objektets attributmetadata
Tilpasse metadata til objektrelationer
Forespørg på metadata ved hjælp af JavaScript

Microsoft Dynamics 365

© 2017 Microsoft. Alle rettigheder forbeholdes. Ophavsret