Étendre Universal Resource Scheduling avec Universal FetchXML
UFX est un langage de requête avancée qui vous permet d’interroger des données à l’aide du FetchXML dynamique, et de mettre en forme et préparer les données résultantes pour qu’elles soient utilisées par la solution Universal Resource Scheduling (URS). Ce langage de requête vous permet de créer des requêtes personnalisées pour personnaliser et étendre le tableau de planification et les filtres de l’Assistant Planifier pour répondre aux besoins métier précis de l’organisation.
UFX est composé de deux composants le conteneur UFX et la requête UFX.
Conteneur UFX simple
Un conteneur UFX contient des données entrées statiques. Dans la mémoire, il se présente sous forme de dictionnaire avec des clés et des valeurs. Il peut être sérialisé dans JSON et XML. Les données saisies permettent à une Requête UFX d’interroger les données à partir de lui, et au à l’interface utilisateur client de s’y lier.
Pour des raisons pratiques et de performances le conteneur dans la mémoire est mis en œuvre au-dessus de l’objet
Entity
du SDK des applications Dynamics 365.
Exemple de conteneur contenant deux valeurs.
Dans la mémoire
clé | valeur | type |
---|---|---|
nom | John | chaîne |
tage | 36 | int |
Dans JSON :
{
"name": "John",
"age": 36
}
Dans XML :
<bag>
<name ufx-type="string">John</name>
<age ufx-type="int">36</age>
</bag>
Types pris en charge par UFX
Un conteneur UFX peut contenir des valeurs de plusieurs types. Ils sont classés en trois classes types :
Catégorie | valeur |
---|---|
Types simples | bool (Boolean) , int (Int32) , long (Int64) , double (Double) , decimal (Decimal) , datetime (DateTime) , guid (Guid) , string (String) Types simples spécifiques à Dynamics 365 : money (Money) , option (OptionSet) , lookup (EntityReference) |
Autres conteneurs | bag (Entity) |
Liste des conteneurs | list (EntityCollection) |
Voici un exemple de conteneur JSON contenant plus de types :
{
"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" }
]
}
Le même conteneur en 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>
Présentation des requêtes UFX
Les requêtes UFX sont entrées sous forme de Conteneurs UFX basés sur XML. Les propriétés dans le conteneur peuvent contenir des Instructions UFX pour interroger des données de manière dynamique. Une requête UFX s’exécute sur les objets dans la mémoire, pas XML. Seules les instructions sont saisies en XML. Les résultats peuvent être sérialisés en JSON ou XML.
La requête UFX suivante définit la propriété accounts
dans le conteneur avec l’instruction UFX source
. Le FetchXML intégré est alors exécuté par Dynamics 365 et la propriété accounts
devient une liste de conteneurs, ou une EntityCollection
, car chaque conteneur est une instance d’un enregistrement de compte de 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>
Une requête UFX est traitée de manière séquentielle et peut contenir de nombreuses requêtes FetchXML.
Voici une extraction du résultat de la requête UFX précédente sérialisée en XML. Observez que certaines valeurs ont des métadonnées les décrivant davantage.
<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>
L’instruction UFX select
prend une expression XPath qui sélectionne des valeurs dans le conteneur actuel.
<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>
Conteneur résultant en XML :
<bag>
<first_account_name ufx-type="string">Fourth Coffee (sample)</first_acount_name>
</bag>
Certainement l’aspect le plus puissant d’une requête UFX est sa capacité de générer dynamiquement FetchXML selon des données entrées.
Dans l’exemple ci-dessous, nous recherchons des comptes par une valeur fournie par l’utilisateur et disponibles sous forme de conteneur UFX via la variable $input
XPath. Notez les instructions UFX si et valeur pour l’élément 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>
Si la propriété NameFilter
dans le conteneur d’entrée contenait %city%
, la condition FetchXML produite exécutée par Dynamics 365 ressemblerait à cela.
<condition attribute="name" operator="like" value="%city%" />
Clés, valeurs et métadonnées
Un conteneur UFX contient des clés et des valeurs, certaines valeurs ayant des métadonnées supplémentaires pour les décrire.
Par exemple, une valeur de type lookup (EntityReference)
. Interrogée par Dynamics 365 via FetchXML, elle renvoie le nom logique de l’entité et le nom complet formaté de l’enregistrement. Les conteneur UFX conservent ces informations supplémentaires sous forme de métadonnées associées à la principale valeur.
Sérialisée en JSON, une lookup
avec des métadonnées ressemble à ce qui suit :
{
"primarycontactid": "7e6e39dd-34a1-e611-8111-00155d652f01",
"primarycontactid@ufx-type": "lookup",
"primarycontactid@ufx-logicalname": "contact",
"primarycontactid@ufx-formatvalue": "Susanna Stubberod (sample)"
}
Dans XML :
<primarycontactid ufx-type="lookup" ufx-formatvalue="Susanna Stubberod (sample)" ufx-logicalname="contact">7e6e39dd-34a1-e611-8111-00155d652f01</primarycontactid>
Données XPath via Dynamics 365
Avec des données saisies dans un conteneur UFX, une requête UFX peut les voir dans un format structuré et utiliser XPath pour parcourir les données et sélectionner des valeurs de celles-ci.
Une expression XPath spécifiée dans une instruction UFX voit les données dans le conteneur de manière similaire à la forme sérialisé en XML dans le conteneur. Toutefois, les données sont stockées dans des objets .NET dans la mémoire (dans les instances de type Entity
et EntityCollection
) et pas dans les documents XML.
Annexe A : Référence au type UFX
Remarque : Tous les types UFX prennent en charge les métadonnées ufx-type
et ufx-formatvalue
. Les métadonnées supplémentaires sont décrites en regard de chaque type dans le tableau ci-dessous.
Nom du contrat UFX | Code de type d’attribut | Nom .NET | Métadonnées UFX |
---|---|---|---|
bool | Booléen | Booléen | |
int | Entier | Int32 | |
Entier long | BigInt | Int64 | |
double | Double | Double | |
décimal | Décimal | Décimal | |
datetime | Date/Heure | Date/Heure | |
GUID | Uniqueidentifier | GUID | |
chaîne | Mémo | Chaîne | |
devise | Monétaire | Monétaire | |
option | Liste déroulante | OptionSetValue | |
recherche | Recherche | EntityReference | ufx-logicalname |
Conteneur | S.o. | Entity | ufx-id ufx-logicalname |
Liste | S.o. | EntityCollection | |
S.o. | S.o. | AliasedValue | ufx-aliasentity ufx-aliasattribute |
Annexe B : Instructions de requête UFX
Les instructions UFX peuvent être utilisées sur les propriétés de conteneur et sur les éléments XML d’une requête FetchXML.
Instructions de conteneur UFX
Attribut | Value | Description |
---|---|---|
ufx:if |
Xpath | Teste l’expression XPath et traite uniquement la propriété si le test renvoie true |
ufx:source |
fetch |
Exécute l’élément XML <fetch> intégré et attribue le résultat à la propriété |
ufx:select |
Xpath | Exécute l’expression XPath et attribue le résultat à la propriété Lors de l’interrogation d’un bag ou d’une list , un bag enfant facultatif dans le formulaire XML peut être spécifié pour transformer le résultat de l’expression XPath |
Instructions FetchXML UFX
Élément | Attribut | Value | Description |
---|---|---|---|
Tous les éléments | ufx:if |
Xpath | Teste l’expression XPath et émet uniquement l’élément XML si les tests aboutissent |
ufx:apply |
select |
Xpath | Effectue une boucle sur le jeux de nœuds renvoyé par l’expression XPath et sort les éléments XML enfants une fois pour chaque nœud |
ufx:value |
select |
Xpath | Exécute l’expression XPath et génère le résultat dans l’élément XML actuel |
ufx:value |
attribute |
nom de l’attribut | Attribue le résultat de l’expression XPath au nom de l’attribut spécifié dans l’élément XML actuel |
Annexe C : Fonctions XPath UFX
UFX ajoute un certain nombre de nouvelles fonctions en plus de celles disponibles en mode natif dans XPath.
datetime()
- datetime() : Renvoie l’heure actuelle en UTC
list()
- list(bag | list, ...[bag | list]): prend un certain nombre de valeurs
bag
oulist
comme entrées et les aplatit en une seulelist
lookup-to-list()
- lookup-to-list(lookup, ...[lookup]): prend un certain nombre de valeurs
lookup
, convertit chacune d’elles en unbag
avec le jeu de métadonnéesufx-id
etufx-logicalname
, et les aplatit en une seulelist
option-to-list()
- option-to-list(option, ...[option]): prend un certain nombre de valeurs
option
, convertit chacune d’elles en unbag
avec une seule propriétéoption
, et les aplatit en une seulelist
order()
- order(list, string, bool) : Classe une liste en fonction d’une propriété dans chaque conteneur. La propriété est spécifiée dans l’argument 2, l’ordre décroissant est spécifié dans l’argument 3.
- order(list, list) : Classe une liste en fonction de plusieurs ordres de tri spécifiés en tant que liste dans l’argument 2. Chaque
bag
de la deuxième liste peut avoir une propriéténame
etdescending
iif()
- iif(any, any, any) : Si l’argument 1 a la valeur true, renvoie l’argument 2, sinon renvoie l’argument 3
Annexe D : Variables XPath UFX
Nom | Description |
---|---|
$input | bag disponible pour la requête UFX avec des valeurs d’entrée |
$null | Constante Null. Sélectionner $null sur une propriété supprime la propriété du conteneur |
$current | Référence au conteneur en cours de traitement par la requête UFX |
Voir aussi
Notes de publication sur l’extensibilité de Universal Resource Scheduling