Condividi tramite


Estendere Universal Resource Scheduling con Universal FetchXML

UFX è un linguaggio di query avanzato che consente di eseguire query sui dati utilizzando FetchXML dinamico nonché di modellare e preparare i dati risultanti per il consumo mediante la soluzione Universal Resource Scheduling (URS). Questo linguaggio di query consente di creare query personalizzate per personalizzare ed estendere i filtri della scheda di pianificazione e dell'assistente di pianificazione allo scopo di soddisfare le esigenze specifiche dell'organizzazione.

UFX include due componenti, ovvero Contenitore UFX e Query UFX.

Contenitore UFX semplice

Un contenitore UFX contiene dati tipizzati statici. In memoria, è rappresentato come un dizionario con chiavi e valori. Può essere serializzato in formato JSON e XML. L'avere dati tipizzati consente a una query UFX di eseguire query sui dati a partire dagli stessi e all'interfaccia utente client di eseguire l'associazione ai dati.

Per motivi pratici e legati alle prestazioni, il contenitore in memoria viene implementato sull'oggetto Entity SDK delle app Dynamics 365.

Esempio di contenitore con due valori.

In memoria:

key valore tipo
nome John stringa
età 36 int

In JSON:

{
    "name": "John",
    "age": 36
}

In XML:

<bag>
    <name ufx-type="string">John</name>
    <age ufx-type="int">36</age>
</bag>

Tipi UFX supportati

Un contenitore UFX può contenere valori di molti tipi. Questi sono categorizzati in tre classi di tipi:

Categoria. valore
Tipi semplici bool (Boolean), int (Int32), long (Int64), double (Double), decimal (Decimal), datetime (DateTime), guid (Guid), string (String)
Tipi semplici specifici di Dynamics 365: money (Money), option (OptionSet), lookup (EntityReference)
Altri contenitori bag (Entity)
Elenco di contenitori list (EntityCollection)

Di seguito è riportato un contenitore JSON di esempio contenente più tipi:

{
    "citizen": true,          // implicit bool
    
    "age": 36,                // explicit int
    "age@ufx-type": "int",

    "name": {                 // nested bag
        "first": "John",
        "last": "Doe"
    },

    "children": [             // list of bags
        { "name": "Sam" },
        { "name": "Judy" }
    ]
}

Lo stesso contenitore in XML:

<bag>
    <citizen ufx-type="bool">true</citizen>

    <age ufx-type="int">36</age>

    <name ufx-type="bag">
        <first ufx-type="string">John</first>
        <last ufx-type="string">Doe</last>
    </name>

    <children ufx-type="list">
        <bag>
            <name ufx-type="string">Sam</name>
        </bag>
        <bag>
            <name ufx-type="string">Judy</name>
        </bag>
    </children>
</bag>

Introduzione alle query UFX

Le query UFX sono scritte come contenitori UFX basati su XML. Le proprietà nel contenitore possono contenere direttive UFX per eseguire query sui dati in modo dinamico. Una query UFX viene eseguita negli oggetti in memoria, non in XML. Solo le direttive sono scritte in XML. Il relativo output può essere serializzato in JSON o XML.

La seguente query UFX definisce la proprietà accounts nel contenitore con la direttiva UFX source . Ciò risulta nell'esecuzione di FetchXML inline da parte di Dynamics 365 e nella trasformazione della proprietà accounts in un elenco di contenitori, o una proprietà EntityCollection, con ogni contenitore che è un'istanza di un record di account di Dynamics 365.

<bag xmlns:ufx="https://schemas.microsoft.com/dynamics/2017/universalfetchxml">
    <accounts ufx:source="fetch">
        <fetch top="10">
            <entity name="account" />
        </fetch>
    </accounts>
</bag>

Una query UFX viene elaborata in modo sequenziale e può contenere molte query FetchXML.

Di seguito è illustrato un frammento del risultato della query UFX precedente serializzata in XML. Da notare che alcuni valori hanno metadati che li descrivono ulteriormente.

<bag>
  <accounts ufx-type="list">
    <bag ufx-id="166e39dd-34a1-e611-8111-00155d652f01" ufx-logicalname="account">
      <accountid ufx-type="guid">166e39dd-34a1-e611-8111-00155d652f01</accountid>
      <accountnumber ufx-type="string">ABSS4G45</accountnumber>
      <name ufx-type="string">Fourth Coffee (sample)</name>
      <statecode ufx-type="option" ufx-formatvalue="Active">0</statecode>
      <websiteurl ufx-type="string">https://www.fourthcoffee.com/</websiteurl>
      <primarycontactid ufx-type="lookup" ufx-formatvalue="Yvonne McKay (sample)" ufx-logicalname="contact">7c6e39dd-34a1-e611-8111-00155d652f01</primarycontactid>
      ...
    </bag>
    <bag ufx-type="bag" ufx-id="186e39dd-34a1-e611-8111-00155d652f01" ufx-logicalname="account">
      <accountid ufx-type="guid">186e39dd-34a1-e611-8111-00155d652f01</accountid>
      <accountnumber ufx-type="string">ACTBBDC3</accountnumber>
      <name ufx-type="string">Litware, Inc. (sample)</name>
      <statecode ufx-type="option" ufx-formatvalue="Active">0</statecode>
      <websiteurl ufx-type="string">https://www.litwareinc.com/</websiteurl>
      <primarycontactid ufx-type="lookup" ufx-formatvalue="Susanna Stubberod (sample)" ufx-logicalname="contact">7e6e39dd-34a1-e611-8111-00155d652f01</primarycontactid>
      ...
    </bag>
    ...
  </accounts>
</bag>

La direttiva UFX select accetta un'espressione XPath che seleziona valori nel contenitore corrente.

<bag xmlns:ufx="https://schemas.microsoft.com/dynamics/2017/universalfetchxml">
    <accounts ufx:source="fetch">
        <fetch top="10">
            <entity name="account" />
        </fetch>
    </accounts>

    <first_account_name ufx:select="accounts/bag[1]/name" />

    <!-- null values remove properties from the bag -->
    <accounts ufx:select="$null" />
</bag>

Il contenitore risultante in XML:

<bag>
    <first_account_name ufx-type="string">Fourth Coffee (sample)</first_acount_name>
</bag>

L'aspetto più avanzato di una query UFX è certamente la relativa capacità di generare dinamicamente FetchXML in base a dati di input.

Nell'esempio seguente, cerchiamo account in base a un valore fornito dall'utente e disponibile come contenitore UFX mediante la variabile $input di XPath. Notare le direttive UFX if e value nell'elemento condition.

<bag xmlns:ufx="https://schemas.microsoft.com/dynamics/2017/universalfetchxml">
    <accounts ufx:source="fetch">
        <fetch top="10">
            <entity name="account">
                <filter>
                    <condition attribute="name" operator="like" ufx:if="$input/NameFilter">
                        <ufx:value select="$input/NameFilter" attribute="value" />
                    </condition>
                </filter>
            </entity>
        </fetch>
    </accounts>
</bag>

Se la proprietà NameFilter nel contenitore di input contenesse %city% la condizione FetchXML prodotta eseguita da Dynamics 365 sarebbe quella illustrato di seguito.

<condition attribute="name" operator="like" value="%city%" />

Chiavi, valori e metadati

Un contenitore UFX contiene chiavi e valori, con alcuni valori che hanno metadati aggiuntivi che li descrivono ulteriormente.

Un esempio potrebbe essere un valore di tipo lookup (EntityReference). Quando ne viene eseguita la query da Dynamics 365 mediante FetchXML, restituirà il nome logico dell'entità nonché il nome visualizzato formattato del record. Il contenitore UFX conserva queste informazioni aggiuntive come metadati associati al valore primario.

Serializzato in JSON, un valore lookup con metadati appare come segue:

{
    "primarycontactid": "7e6e39dd-34a1-e611-8111-00155d652f01",
    "primarycontactid@ufx-type": "lookup",
    "primarycontactid@ufx-logicalname": "contact",
    "primarycontactid@ufx-formatvalue": "Susanna Stubberod (sample)"
}

In XML:

<primarycontactid ufx-type="lookup" ufx-formatvalue="Susanna Stubberod (sample)" ufx-logicalname="contact">7e6e39dd-34a1-e611-8111-00155d652f01</primarycontactid>

XPath su dati di Dynamics 365

La presenza di dati in un contenitore UFX tipizzato consente a una query UFX di visualizzarli in un formato strutturato e di utilizzare XPath per attraversare i dati e selezionare i valori dagli stessi.

Per un'espressione XPath specificata in una direttiva UFX i dati nel contenitore sono simili alla struttura del contenitore in formato serializzato XML. Tuttavia, i dati sono archiviati in oggetti .NET in memoria (in istanze dei tipi Entity e EntityCollection) e non nei documenti XML.

Appendice A: riferimento ai tipi UFX

Nota: tutti i tipi UFX supportano i metadati ufx-type e ufx-formatvalue. Ulteriori metadati sono descritti accanto a ogni tipo nella tabella sottostante.

Nome UFX Codice tipo di attributo Nome .NET Metadati UFX
bool booleano booleano
int Integer Int32
long BigInt Int64
double Double Double
decimal Decimal Decimal
datetime DateTime DateTime
guid Uniqueidentifier GUID
stringa Memo Stringa
money Money Money
option Gli attributi di tipo Picklist OptionSetValue
lookup Ricerca EntityReference ufx-logicalname
bag N/D Entità ufx-id
ufx-logicalname
elenco N/D EntityCollection
N/D N/D AliasedValue ufx-aliasentity
ufx-aliasattribute

Appendice B: direttive di query UFX

Le direttive UFX possono essere utilizzate nelle proprietà di contenitori e negli elementi XML di una query FetchXML.

Direttive di contenitori UFX

Attributo Value Descrizione
ufx:if XPath Verifica l'espressione XPath ed elabora solo la proprietà se il test restituisce true
ufx:source fetch Esegue l'elemento XLM <fetch> inline e assegna il risultato alla proprietà
ufx:select XPath Esegue l'espressione XPath e assegna il risultato alla proprietà
Quando si esegue una query per un bag o list, un bag figlio facoltativo in formato XML può essere specificato per trasformare il risultato dell'espressione XPath

Direttive FetchXML UFX

Elemento Attributo Value Descrizione
Tutti gli elementi ufx:if XPath Verifica l'espressione XPath ed emette l'elemento XML solo se il test riesce
ufx:apply select XPath Esegue il ciclo sul set di nodi restituito dall'espressione XPath e genera gli elementi XML figlio una volta per ogni nodo
ufx:value select XPath Esegue l'espressione XPath e genera il risultato nell'elemento XML corrente
ufx:value attribute nome attributo Assegna il risultato dell'espressione XPath al nome di attributo specificato nell'elemento XML corrente

Appendice C: funzioni XPath UFX

UFX aggiunge varie nuove funzioni oltre a quelle originariamente disponibili in XPath.

datetime()

  • datetime(): restituisce l'orario corrente in UTC

list()

  • list(bag | list, ...[bag | list]): accetta un numero di valori bag o list in input e li unisce in un unico list

lookup-to-list()

  • lookup-to-list(lookup, ...[lookup]): accetta vari valori lookup, li converte in un bag con i set di metadati ufx-id e ufx-logicalname e li unisce in un unico list

option-to-list()

  • option-to-list(option, ...[option]): accetta un numero di valori option, li converte in un bag con un'unica proprietà option e li unisce in un unico list

order()

  • order(list, string, bool): ordina un elenco in base a una proprietà in ogni contenitore. La proprietà è specificata nell'argomento 2, decrescente è specificato nell'argomento 3.
  • order(list, list): ordina un elenco in base a molteplici ordinamenti specificati come elenco nell'argomento 2. Ogni bag nel secondo elenco può avere una proprietà name e descending

iif()

  • iif(any, any, any): se l'argomento 1 è true, restituisce l'argomento 2, altrimenti restituisce l'argomento 3

Appendice D: variabili XPath UFX

Nome Descrizione
$input Un bag disponibile per la query UFX con valori di input
$null Una costante null. La selezione di $null in una proprietà rimuove la proprietà dal contenitore
$current Riferimento al contenitore corrente elaborato dalla query UFX

Vedi anche

Comprendere e personalizzare la corrispondenza delle risorse in Universal Resource Scheduling

Note sulla versione dell'estendibilità di Universal Resource Scheduling