Créateur de requêtes FetchXML
<FetchXmlBuilder> modifie une requête FetchXML sans que personne n’écrive FetchXML. Il couvre les parties du langage que les gens utilisent réellement — la table, les colonnes qu’il renvoie, la façon dont les lignes sont triées, ainsi qu’un arbre de filtres de conditions et de groupes imbriqués — et il rejoint les tables associées, les agrège, et exécute ce qu’il a construit.
Réagir seulement, pour l’instant
Ce composant existe uniquement sur la pile React — il n’existe pas encore d’équivalent Blazor. Un portail Blazor qui doit stocker une requête FetchXML peut toujours le faire ; ce qu’il n’a pas, c’est cet éditeur pour en construire une.
Essaie
Le vrai composant par rapport aux métadonnées de cet environnement. Choisissez une table, ajoutez une colonne ou une condition, rejoignez une table associée, et regardez le panneau FetchXML suivre — puis appuyez sur Exécuter pour voir ce que correspond la requête.
Ce n’est pas la même chose que FetchXMLBuilder
Cette page concerne le composant.
FetchXMLBuilderest la classe C# qui compose le même XML en code, pour un appelant côté serveur qui construit une requête manuellement. Ils produisent la même chose et aucun n’a besoin de l’autre.
Les métadonnées sont obligatoires, non optionnelles
Chaque tableau, colonne et relation est choisie à partir de ce que l’environnement possède réellement. C’est délibéré : un nom logique tapé à la main produit FetchXML qui analyse parfaitement puis échoue sur Dataverse, ce qui est le pire type d’erreur à donner à quelqu’un. Le usePowerPortalsProFetchXmlMetadata crochet connecte le constructeur aux points de terminaison de métadonnées mises en cache du framework, de sorte que les sélectionneurs partagent ce que les grilles sur la même page ont déjà récupéré.
// La page de tout le câblage sur un portail.
import { FetchXmlBuilder, usePowerPortalsProFetchXmlMetadata } from '@powerportalspro/react-fluent';
export function QueryEditor() {
const metadata = usePowerPortalsProFetchXmlMetadata();
const [fetchXml, setFetchXml] = useState('');
return <FetchXmlBuilder value={fetchXml} onChange={setFetchXml} metadata={metadata} />;
}
Les allers-retours de requêtes
Le constructeur analyse FetchXML dans un modèle de document et le réécrit. Tout ce pour quoi il n’a pas d’éditeur — un attribut d’une version plus récente de la plateforme, un élément écrit par un autre outil — est conservé sans être modifié plutôt que supprimé au chargement, donc ouvrir une requête dans l’éditeur et l’enregistrer ne vous coûte jamais une partie discrètement.
Ce que cela signifie pour une requête sauvegardée
La mise en forme n’est pas préservée. L’indentation et la citation des attributs sont normalisées à la sortie, donc une requête resauvegardée via le constructeur est la même requête plutôt que le même texte.
Fournir une requête
Il y a trois entrées, et toutes trois passent par le même lecteur :
- L’hélice
value. Fournissez-laonChangepour un composant contrôlé, ou utilisez-ladefaultValueet laissez le constructeur s’approprier son état. - Le panneau FetchXML. Collez ou tapez une requête et l’éditeur se reconstruit à partir d’elle environ une seconde après que vous ayez arrêté de taper.
- Une vue sauvegardée. Commencez par une vue dans l’en-tête Filtres qui liste les vues de la table et prend toute la requête de celle que vous choisissez. C’est une copie — rien n’est écrit dans la vue.
Tout ce qui arrive est vérifié en premier. Un XML mal formé est signalé avec sa ligne et sa colonne, tout comme tout ce qui ferait afficher à l’éditeur autre chose que ce qui a été écrit — un opérateur ou un type de lien qu’il ne connaît pas, une requête ne nommant aucune table. Ces éléments sont catégoriquement refusés et la requête déjà à l’écran est laissée intacte. Tout le reste est rapporté et toujours appliqué : un élément ou un attribut mal orthographié, deux tables partageant un alias, une condition litue d’un alias que rien ne déclare.
Tableaux associés
Une jointure est ajoutée à partir du sélecteur de relations, donc les from colonnes et to proviennent de la relation plutôt que de la mémoire. Ce qu’une jointure peut alors apporter dépend de son type :
- Les types retournant —
inner,outeretmatchfirstrowusingcrossapply— ramènent les colonnes de la table associée, afin que leurs colonnes puissent être projetées, triées et comparées. - Les types de filtrage —
exists,in,any,not anyetall— retournent la ligne au maximum une fois et aucune des colonnes associées. L’éditeur supprime l’alias lorsque vous en basculez, donc le nom est libre pour une autre jointure. - Sans ligne associée est un préréglage plutôt qu’un type de lien : FetchXML n’en a pas pour lui, donc l’éditeur écrit la jointure externe et le test nul sur la clé jointe que la plateforme attend, et garde les deux en même ordre.
À propos de « tous »
FetchXML
allne signifie pas ce que son nom suggère — il correspond à des lignes dont les lignes sont apparentées dont aucune ne satisfait au filtre, etnot allest documenté comme équivalent àany. Chaque type est étiqueté selon son rôle plutôt que son nom, et une action Invert conditions sur un groupe de filtres exprime la lecture que les gens souhaitent généralement.
Requêtes agrégées
Activez l’agrégat dans la section Colonnes et chaque colonne indique ce qu’elle apporte — une valeur calculée sur les lignes, ou la chose qui les regroupe. Les fonctions proposées se resserrent au type de la colonne, les alias deviennent nécessaires et sont remplis pour vous, une colonne de date groupée gagne une partie date, et le tri change vers les alias, car les lignes d’une requête agrégée sont des groupes et des valeurs calculées sans colonnes à trier.
<fetch aggregate="true">
<entity name="account">
<attribute name="revenue" alias="sum_revenue" aggregate="sum" />
<attribute name="address1_city" alias="group_address1_city" groupby="true" />
<order alias="group_address1_city" />
</entity>
</fetch>
allowAggregate={false} retire le commutateur, pour un hôte qui lit les lignes plutôt que les totaux — une règle évaluée un enregistrement à la fois, un filtre sauvegardé, n’importe où une seule ligne de valeurs calculées ne serait pas une réponse. Elle est absente plutôt que désactivée, car aucun changement de requête ne la ramènerait. La seule exception est une requête qui s’agrége déjà : elle conserve ses contrôles quel que soit le réglage du prop, donc une requête collée dans le panneau FetchXML peut toujours être modifiée en une requête ordinaire.
// Le commutateur Aggregate n’est pas proposé du tout.
<FetchXmlBuilder
metadata={metadata}
table="contact"
allowAggregate={false}
value={fetchXml}
onChange={setFetchXml}
/>
Montage d’une partie
Chaque section peut être désactivée, et les sections sont exportées individuellement pour une mise en page qui en a besoin ailleurs — montez <FetchXmlBuilderProvider> et placez vous-même les FetchXml*Section composants. Omettre une section supprime son interface, jamais le FetchXML sous-jacent : les colonnes d’une requête survivent intactes avec columns: false.
// Un éditeur de règles uniquement filtré, épinglé sur une seule table.
<FetchXmlBuilder
metadata={metadata}
table="contact"
sections={{ table: false, columns: false, sorts: false, options: false }}
value={fetchXml}
onChange={setFetchXml}
/>
Restriction des tables
allowedTables Réduit le sélecteur de table aux noms logiques que vous listez — pour une surface qui n’a pas à interroger tout l’environnement, comme un constructeur de rapports sur la poignée de tables qu’un portail expose. Omettez-le et chaque table est proposée. Cela réduit ce qui peut être choisi, pas ce qui peut être montré : une requête qui nomme déjà une table en dehors de la liste la conserve plutôt que d’être réécrite silencieusement, et une table apparentée est toujours nommée par son nom d’affichage chaque fois qu’une jointure la mentionne. Les jointures elles-mêmes ne sont pas restreintes, car elles suivent des relations — une propriété de la table déjà choisie.
// Le sélectionneur ne propose ces trois et rien d’autre.
<FetchXmlBuilder
metadata={metadata}
allowedTables={['account', 'contact', 'opportunity']}
value={fetchXml}
onChange={setFetchXml}
/>
Exécution de la requête
Fournit renderResults et le constructeur développe un panneau Résultats avec un bouton Exécuter, et décide quand il peut être pressé. Afficher les lignes prend un client de données que le constructeur n’a délibérément pas, donc ce résultat vous appartient — sur un portail, cela signifie généralement celui du <MainGrid> framework plutôt que la requête qu’il rend. Laissez l’hélice éteint et le panneau n’est pas là.
<FetchXmlBuilder
metadata={metadata}
value={fetchXml}
onChange={setFetchXml}
// Le constructeur fournit le bouton ; cela indique à quoi ressemble un résultat.
renderResults={(runnable) => (
<MainGrid
key={runnable.fetchXml}
tableName={runnable.tableName}
customViewDefinitions={[{
id: BUILDER_VIEW_ID,
displayName: 'Builder query',
tableName: runnable.tableName,
fetchXml: runnable.fetchXml,
columns: runnable.columns.map((columnName) => ({ columnName, width: 200 })),
}]}
viewId={BUILDER_VIEW_ID}
/>
)}
/>
