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
olist
in input e li unisce in un unicolist
lookup-to-list()
- lookup-to-list(lookup, ...[lookup]): accetta vari valori
lookup
, li converte in unbag
con i set di metadatiufx-id
eufx-logicalname
e li unisce in un unicolist
option-to-list()
- option-to-list(option, ...[option]): accetta un numero di valori
option
, li converte in unbag
con un'unica proprietàoption
e li unisce in un unicolist
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
edescending
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