Joindre des tables à l’aide de QueryExpression
Utilisez la propriété QueryExpression.LinkEntities pour décrire les données des tables associées à renvoyer avec votre requête. Cette propriété contient une collection de LinkEntity instances qui décrivent :
- Quelles lignes de table associées renvoyer
- Sur quelles valeurs de colonne baser la jointure
- Quelles colonnes de ces enregistrements renvoyer
- Tous les filtres à appliquer avec la jointure
Notes
La propriété LinkEntities
est en lecture seule. Vous pouvez définir LinkEntity
instances à cette collection en utilisant l’initialisation d’objet ou en utilisant le Méthode QueryExpression.AddLink.
Vous pouvez aussi utiliser System.Collections.ObjectModel.Collection<T> méthodes le LinkEntities
la propriété hérite.
Propriétés LinkEntity
Le tableau suivant propose des détails sur les propriétés LinkEntity :
Property | Description |
---|---|
LinkFromEntityName | Nom logique de l’entité à lier. Pour un LinkEntity qui n’est pas imbriqué, utilisez la même valeur que la propriété QueryExpression.EntityName.Pour un LinkEntity imbriqué dans une collection LinkEntity.LinkEntities, utilisez la valeur de LinkEntity.LinkToEntityName à partir de l’entité de lien parent. |
LinkToEntityName | Nom logique de l’entité à lier. |
LinkFromAttributeName | Nom logique de l’Attribut de l’entité à lier. |
LinkToAttributeName | Nom logique de l’Attribut de l’entité à lier. |
JoinOperator | Opérateur de jonction. Utilisez la valeur de l’un des membres de l’énumération JoinOperator . La valeur par défaut est Inner , ce qui limite les résultats aux lignes dont les valeurs correspondent dans les deux tableaux.Les autres valeurs valides sont : - LeftOuter Inclut les résultats de la ligne parent qui n’ont pas de valeur correspondante.- Natural Une seule valeur des deux colonnes jointes est renvoyée si une opération de jointure égale est effectuée et que les deux valeurs sont identiques.Ces membres considéraient comme des des JoinOperators avancés : - Exists - In - MatchFirstRowUsingCrossApply Ces membres sont utilisés pour filtrer les valeurs dans les enregistrements associés : - All - Any - NotAll - NotAny |
EntityAlias | Alias de la table. |
Columns | Colonnes à inclure pour la table. Ajoutez ces colonnes à la table jointe à l’aide de a ColumnSet. Apprenez à sélectionner des colonnes à l’aide de QueryExpression |
LinkCriteria | Les expressions de filtre de condition et logiques complexes qui filtrent les résultats de la requête. Découvrez comment filtrer les lignes à l’aide de QueryExpression |
LinkEntities | Collection de liens entre entités pouvant inclure des liens imbriqués. Jusqu’à 15 liens au total peuvent être inclus dans une requête |
Notes
La signification des propriétés LinkEntity.LinkFromAttributeName et LinkEntity.LinkToAttributeName est à l’opposé de la from
correspondante et to
attributs dans FetchXml. En savoir plus sur l’utilisation des attributs from
et to
avec FetchXml
Exemple LinkEntity
La requête suivante renvoie jusqu’à cinq enregistrements des tables compte et contact en fonction des Colonne de recherche PrimaryContactId dans l’enregistrement du compte. Il s’agit d’une relation plusieurs-à-un :
QueryExpression query = new("account")
{
TopCount = 5,
ColumnSet = new ColumnSet("name"),
LinkEntities = {
new LinkEntity()
{
LinkFromEntityName = "account",
LinkToEntityName = "contact",
LinkFromAttributeName = "primarycontactid",
LinkToAttributeName = "contactid",
JoinOperator = JoinOperator.Inner,
EntityAlias = "contact",
Columns = new ColumnSet("fullname")
}
}
};
Les résultats ressemblent à ce qui suit :
-----------------------------------------------------------------
| name | contact.fullname |
-----------------------------------------------------------------
| Litware, Inc. (sample) | Susanna Stubberod (sample) |
-----------------------------------------------------------------
| Adventure Works (sample) | Nancy Anderson (sample) |
-----------------------------------------------------------------
| Fabrikam, Inc. (sample) | Maria Campbell (sample) |
-----------------------------------------------------------------
| Blue Yonder Airlines (sample) | Sidney Higa (sample) |
-----------------------------------------------------------------
| City Power & Light (sample) | Scott Konersmann (sample) |
-----------------------------------------------------------------
Méthodes AddLink
Vous pouvez composer l’intégralité de la requête à l’aide de l’initialisation d’objet comme indiqué, mais nous vous recommandons d’utiliser QueryExpression.AddLink et LinkEntity.AddLink méthodes. Ces méthodes renvoient une référence au lien créé afin que vous puissiez facilement accéder et modifier la requête au sein de la collection. Par exemple, si vous composez la requête de cette façon à l’aide de la méthode QueryExpression.AddLink :
var query = new QueryExpression("account")
{
TopCount = 5,
ColumnSet = new ColumnSet("name"),
};
// Link to primary contact
LinkEntity linkedPrimaryContact = query.AddLink(
linkToEntityName: "contact",
linkFromAttributeName: "primarycontactid",
linkToAttributeName: "contactid",
joinOperator: JoinOperator.Inner);
linkedPrimaryContact.EntityAlias = "primarycontact";
linkedPrimaryContact.Columns = new ColumnSet("fullname");
Vous pouvez étendre la requête à l’aide de la méthode LinkEntity.AddLink pour inclure des informations sur le utilisateur propriétaire pour le contact lié via l’ linkedPrimaryContact
LinkEntity
instance :
// Link to contact owning user
LinkEntity linkedContactOwner = linkedPrimaryContact.AddLink(
linkToEntityName: "systemuser",
linkFromAttributeName: "owninguser",
linkToAttributeName: "systemuserid",
joinOperator: JoinOperator.Inner);
linkedContactOwner.EntityAlias = "owner";
linkedContactOwner.Columns = new ColumnSet("fullname");
De cette façon, vous pourrez accéder plus facilement aux différentes parties de la requête pour effectuer des ajustements.
Limitations
Vous pouvez ajouter jusqu’à 15 LinkEntity instances à une requête. Chacun LinkEntity
ajoute un JOIN à la requête et augmente le temps d’exécution de la requête. Cette limite sert à protéger les performances. Si vous ajoutez plus de 15 LinkEntity
instances à QueryExpression.LinkEntities, vous obtenez cette erreur d’exécution :
Nom :
TooManyLinkEntitiesInQuery
code :0x8004430D
Nombre :-2147204339
Message :Number of link entities in query exceeded maximum limit.
Relations plusieurs-à-un
L’ exemple précédent est une relation plusieurs-à-un dans laquelle de nombreux enregistrements de compte peuvent faire référence à un enregistrement de contact. Ces informations sont définies dans la relation plusieurs-à-un account_primary_contact du compte, qui a les valeurs suivantes :
Propriété | Valeur | Commentaire |
---|---|---|
SchemaName |
account_primary_contact |
Nom unique de la relation. |
ReferencedEntity |
contact |
La table référencée. Le un dans plusieurs-à-un. LinkToEntityName dans l’exemple précédent. |
ReferencedAttribute |
contactid |
La clé primaire de la table référencée. LinkToAttributeName dans l’exemple précédent. |
ReferencingEntity |
account |
La table avec une colonne de recherche qui fait référence à l’autre table. Le plusieurs dans plusieurs-à-un. LinkFromEntityName dans l’exemple précédent. |
ReferencingAttribute |
primarycontactid |
Le nom de la colonne de recherche. LinkFromAttributeName dans l’exemple précédent. |
RelationshipType |
OneToManyRelationship |
Une relation un-à-plusieurs lorsqu’elle est affichée à partir de la table contact référencée (une).Une relation plusieurs-à-un lorsqu’elle est affichée à partir de la table de référence account (plusieurs) |
Récupérer les informations sur la relation
Vous pouvez utiliser d’autres outils et API pour rechercher des données de relation pour les LinkToEntityName
, LinkToAttributeName
, LinkFromEntityName
et LinkFromAttributeName
valeurs appropriées à utiliser. Pour en savoir plus, consultez :
Exemple de relations Plusieurs-à-un
Le tableau suivant présente les valeurs de relation à utiliser pour une relation plusieurs-à-un :
Property | Valeur des relations | Comment |
---|---|---|
LinkFromEntityName |
ReferencingEntity |
La table référencée. Le plusieurs dans plusieurs-à-un. account dans l’exemple de relations Plusieurs-à-un. Il n’existe aucun paramètre pour cette propriété dans les méthodes AddLink car elle peut être dérivée des propriétés QueryExpression.EntityName ou LinkEntity.LinkToEntityName . |
LinkToEntityName |
ReferencedEntity |
La table avec une clé primaire que les autres tables référencent. Le un dans plusieurs-à-un. contact dans l’exemple de relations Plusieurs-à-un. |
LinkFromAttributeName |
ReferencingAttribute |
Le nom de la colonne de recherche. primarycontactid dans l’exemple de relations Plusieurs-à-un. |
LinkToAttributeName |
ReferencedAttribute |
La clé primaire de la table référencée. contactid dans l’exemple de relations Plusieurs-à-un. |
Relations 1 à N (un-à-plusieurs)
Les relations plusieurs-à-un et un-à-plusieurs sont comme regarder des deux faces d’une pièce de monnaie. La relation existe entre les tables ; par conséquent, la façon dont vous l’utilisez dépend de quelle table est la table de base pour votre requête.
Notes
Si votre table de base contient la colonne de recherche, il s’agit d’une relation plusieurs-à-un. Sinon, c’est une relation un-à-plusieurs.
Vous pouvez récupérer les mêmes données que l’ exemple précédent de la table contact en utilisant la même relation, sauf à partir de la côté de la contact
table. Utilisez les données de la même relation un-à-plusieurs account_primary_contact du contact, mais ajustez les valeurs pour la vue différente de la relation.
var query = new QueryExpression("contact")
{
TopCount = 5,
ColumnSet = new ColumnSet("fullname"),
};
// Link to related account
var linkedPrimaryContact = query.AddLink(
linkToEntityName: "account",
linkFromAttributeName: "contactid",
linkToAttributeName: "primarycontactid",
joinOperator: JoinOperator.Inner);
linkedPrimaryContact.EntityAlias = "account";
linkedPrimaryContact.Columns = new ColumnSet("name");
Pour une relation de type un à plusieurs utilisez les valeurs de relation :
Property | Valeur des relations | Comment |
---|---|---|
LinkFromEntityName |
ReferencedEntity |
La table référencée. Le un dans plusieurs-à-un. contact dans l’exemple de relations un-à-Plusieurs. Il n’existe aucun paramètre pour cette propriété dans les méthodes AddLink car elle peut être dérivée des propriétés QueryExpression.EntityName ou LinkEntity.LinkToEntityName . |
LinkToEntityName |
ReferencingEntity |
La table avec une colonne de recherche qui fait référence à l’autre table. Le plusieurs dans plusieurs-à-un. account dans l’exemple de relations un-à-Plusieurs. |
LinkFromAttributeName |
ReferencedAttribute |
La clé primaire de la table référencée. contactid dans l’exemple de relations un-à-Plusieurs. |
LinkToAttributeName |
ReferencingAttribute |
Le nom de la colonne de recherche. primarycontactid dans l’exemple de relations un-à-Plusieurs. |
Les résultats incluent les mêmes enregistrements et données que l’ exemple précédent utilisant la relation plusieurs-à-un, sauf maintenant l’ entité parent’ est maintenant contact
au lieu de account
.
-----------------------------------------------------------------
| fullname | account.name |
-----------------------------------------------------------------
| Susanna Stubberod (sample) | Litware, Inc. (sample) |
-----------------------------------------------------------------
| Nancy Anderson (sample) | Adventure Works (sample) |
-----------------------------------------------------------------
| Maria Campbell (sample) | Fabrikam, Inc. (sample) |
-----------------------------------------------------------------
| Sidney Higa (sample) | Blue Yonder Airlines (sample) |
-----------------------------------------------------------------
| Scott Konersmann (sample) | City Power & Light (sample) |
-----------------------------------------------------------------
Relations plusieurs-à-plusieurs
Les relations plusieurs-à-plusieurs dépendent d’une table d’intersection. Une table d’intersection ne comporte généralement que quatre colonnes, mais seules deux d’entre elles sont importantes. Les deux colonnes importantes correspondent aux colonnes de la clé primaire des tables participantes.
Par exemple, la table d’intersection TeamMembership
prend en charge la relation plusieurs-à-plusieurs teammembership_association entre les tables SystemUser et Team. Elle permet aux utilisateurs de joindre plusieurs équipes et aux équipes d’avoir plusieurs utilisateurs. TeamMembership
comporte ces colonnes : systemuserid
, teamid
.
Si vous souhaitez récupérer des informations sur les utilisateurs et les équipes auxquelles ils appartiennent à l’aide de la teammembership_association
relation plusieurs-à-plusieurs, vous pouvez utiliser cette QueryExpression requête. :
var query = new QueryExpression("systemuser")
{
TopCount = 2,
ColumnSet = new ColumnSet("fullname"),
};
LinkEntity linkedTeamMemberShip = query.AddLink(
linkToEntityName: "teammembership",
linkFromAttributeName: "systemuserid",
linkToAttributeName: "systemuserid");
LinkEntity linkedTeam = linkedTeamMemberShip.AddLink(
linkToEntityName: "team",
linkFromAttributeName: "teamid",
linkToAttributeName: "teamid");
linkedTeam.EntityAlias = "team";
linkedTeam.Columns = new ColumnSet("name");
Il existe deux LinkEntity instances.
linkedTeamMemberShip
se connectesystemuser
à lateammembership
table d’intersection oùsystemuserid
=systemuserid
.linkedTeam
se connecteteammembership
à la table d’intersection vers l’équipe oùteamid
=teamid
.
Les résultats devraient ressembler à ce qui suit :
--------------------------------------
| fullname | team.name |
--------------------------------------
| FirstName LastName | org26ed931d |
--------------------------------------
| # PpdfCDSClient | org26ed931d |
--------------------------------------
Aucune relation
Il est possible de spécifier LinkFromAttributeName
et LinkToAttributeName
des propriétés à l’aide de colonnes qui ne font pas partie d’une relation définie.
Par exemple, cette requête recherche des paires d’enregistrements dans lesquels la colonne Name d’un enregistrement de compte correspond à la Colonne FullName d’un enregistrement de contact, qu’ils se référencent ou non dans l’une des colonnes de recherche.
var query = new QueryExpression("account")
{
ColumnSet = new ColumnSet("name"),
};
LinkEntity linkedContact = query.AddLink(
linkToEntityName: "contact",
linkFromAttributeName: "name",
linkToAttributeName: "fullname");
linkedContact.EntityAlias = "contact";
linkedContact.Columns = new ColumnSet("fullname");
Notes
Il est important que les colonnes spécifiées dans les propriétés LinkFromAttributeName
et LinkToAttributeName
sont du même type même si elles ne sont pas impliquées dans une relation. L’utilisation de colonnes de types différents nécessitera une conversion de type qui pourrait avoir un impact sur les performances et pourrait échouer pour certaines valeurs de colonne.
Les types de colonnes ne peuvent pas être utilisés dans LinkFromAttributeName
et LinkToAttributeName
propriétés :
- Fichier
- Image
- Champ à sélection multiple
- PartyList
Certaines colonnes peuvent être utilisées dans les propriétés LinkFromAttributeName
et LinkToAttributeName
, mais peuvent entraîner de mauvaises performances :
- Colonnes de type Plusieurs lignes de texte
- Colonnes de type Une seule ligne de texte d’une longueur maximale supérieure à 850
- Colonnes de formule
- Colonnes calculées
- Colonnes logiques
Rechercher des enregistrements qui ne font pas partie d’un ensemble
Vous pouvez utiliser QueryExpression pour créer une requête pour renvoyer les enregistrements qui ne font pas partie d’un ensemble à l’aide d’un jointure externe gauche. Une jointure externe gauche renvoie chaque ligne qui répond à la jointure de la première entrée avec la seconde entrée. Elle renvoie également toute ligne de la première entrée qui n’avait pas de lignes correspondantes dans la seconde entrée. Les lignes sans correspondance de la seconde entrée sont renvoyées comme valeurs nulles.
Vous pouvez effectuer une jointure externe gauche dans QueryExpression
en utilisant la propriété ConditionExpression.EntityName. La propriété EntityName
est valide en termes de conditions, de filtres et de filtres imbriqués. En savoir plus sur les filtres sur LinkEntity
Par exemple, la requête suivante renvoie tous les enregistrements de contact sans contacts.
var query = new QueryExpression(entityName: "account");
query.ColumnSet.AddColumn("name");
query.AddOrder(
attributeName: "name",
orderType: OrderType.Descending);
query.Criteria.AddCondition(
entityName: "contact",
attributeName: "parentcustomerid",
conditionOperator: ConditionOperator.Null);
LinkEntity linkedContact = query.AddLink(
linkToEntityName: "contact",
linkFromAttributeName: "accountid",
linkToAttributeName: "parentcustomerid",
joinOperator: JoinOperator.LeftOuter);
linkedContact.EntityAlias = "contact";
linkedContact.Columns.AddColumn("fullname");
Utiliser les JoinOperators avancés
Ce qui suit Membres JoinOperator ne correspondent pas directement à T-SQL Opérateur REJOINDRE types et utilisation sous-requêtes plutôt. Ces types offrent des fonctionnalités plus avancées que vous pouvez utiliser pour améliorer les performances des requêtes et définir des requêtes plus complexes.
Nom | Description |
---|---|
Exists |
Une variante de Inner qui peut offrir des avantages en termes de performances. Utilise une condition EXISTS dans la clause where . Utiliser Exists lorsque plusieurs copies de la ligne parent ne sont pas nécessaires dans les résultats. En savoir plus sur Exists et In . |
In |
Une variante de Inner qui peut offrir des avantages en termes de performances. Utilise un DANS condition dans la clause Where. Utiliser In lorsque plusieurs copies de la ligne parent ne sont pas nécessaires dans les résultats. En savoir plus sur Exists et In . |
MatchFirstRowUsingCrossApply |
Une variante de Inner qui peut offrir des avantages en termes de performances. Utilisez ce type lorsqu’un seul exemple de ligne correspondante de l’entité liée est suffisant et que plusieurs copies de la ligne parente dans les résultats ne sont pas nécessaires. En savoir plus sur l’utilisation de MatchFirstRowUsingCrossApply |
Utilisez JoinOperator.Exists
ou JoinOperator.In
Exists
et In
sont des variantes de Inner
qui utilisent différentes conditions (EXISTS et IN respectivement) dans la clause where
afin que plusieurs copies de la ligne parente ne soient pas renvoyées dans les résultats. Les deux Exists
et In
ne renvoie pas les valeurs de colonne des lignes d’entité associées.
En utilisant JoinOperator.Exists
ou JoinOperator.In
peut réduire la taille des résultats de requête intermédiaires ou finaux, en particulier lorsqu’il existe de nombreuses lignes liées correspondantes pour les mêmes lignes parent, ou lorsque plusieurs entités de lien sont utilisées avec le même parent. En utilisant JoinOperator.Exists
ou JoinOperator.In
peut améliorer les performances de la requête par rapport à JoinOperator.Inner
car il ne nécessite pas de renvoyer un produit cartésien contenant toutes les permutations possibles de lignes de différentes entités liées pour chaque ligne parent.
Ces JoinOperator
membres peuvent également permettre Dataverse de trouver uniquement la première ligne d’entité liée correspondante pour chaque ligne parent, ce qui est plus efficace que de rechercher toutes les lignes correspondantes dans l’entité liée avec JoinOperator.Inner
.
Exemple avec JoinOperator.Exists
Ces exemples QueryExpression et SQL montrent les modèles appliqués avec JoinOperator.Exists
.
QueryExpression query = new("contact");
query.ColumnSet.AddColumn("fullname");
LinkEntity linkedAccount = query.AddLink(
linkToEntityName: "account",
linkFromAttributeName: "contactid",
linkToAttributeName: "primarycontactid",
joinOperator: JoinOperator.Exists);
linkedAccount.EntityAlias = "account";
linkedAccount.LinkCriteria.AddCondition(
entityName:"account",
attributeName: "statecode",
conditionOperator: ConditionOperator.Equal,
values: 1);
Exemple avec JoinOperator.In
Ces exemples QueryExpression et SQL montrent les modèles appliqués avec JoinOperator.In
.
QueryExpression query = new("contact");
query.ColumnSet.AddColumn("fullname");
LinkEntity linkedAccount = query.AddLink(
linkToEntityName: "account",
linkFromAttributeName: "contactid",
linkToAttributeName: "primarycontactid",
joinOperator: JoinOperator.In);
linkedAccount.EntityAlias = "account";
linkedAccount.LinkCriteria.AddCondition(
entityName: "account",
attributeName: "statecode",
conditionOperator: ConditionOperator.Equal,
values: 1);
Utiliser JoinOperator.MatchFirstRowUsingCrossApply
JoinOperator.MatchFirstRowUsingCrossApply
produit un CROSS APPLY opérateur avec une sous-requête utilisant top 1
suivant ce modèle :
QueryExpression query = new("contact");
query.ColumnSet.AddColumn("fullname");
LinkEntity linkedAccount = query.AddLink(
linkToEntityName: "account",
linkFromAttributeName: "contactid",
linkToAttributeName: "primarycontactid",
joinOperator: JoinOperator.MatchFirstRowUsingCrossApply);
linkedAccount.EntityAlias = "account";
linkedAccount.Columns = new ColumnSet("accountid", "name");
Ceci est équivalent à JoinOperator.LeftOuter
sauf qu’il ne renvoie la ligne parent qu’au plus une fois. Contrairement à JoinOperator.In
et JoinOperator.Exists
, il renvoie les valeurs de colonne de l’une des lignes correspondantes dans la table associée lorsque des lignes correspondantes existent, mais la ligne parent est renvoyée même s’il n’y a aucune ligne correspondante dans le tableau associé. Utilisez cette option lorsqu’un seul exemple de ligne correspondante de la table associée est suffisant et que plusieurs copies de la ligne parent dans les résultats ne sont pas nécessaires.
Étapes suivantes
Découvrez comment trier des lignes.
Notes
Pouvez-vous nous indiquer vos préférences de langue pour la documentation ? Répondez à un court questionnaire. (veuillez noter que ce questionnaire est en anglais)
Le questionnaire vous prendra environ sept minutes. Aucune donnée personnelle n’est collectée (déclaration de confidentialité).