Jointures de listes et projections

Dernière modification : lundi 2 août 2010

S’applique à : SharePoint Foundation 2010

Dans cet article
Jointures et projections en mode liste
Jointures et projections dans les requêtes
Jointures implicites sans élément Joins

Cette rubrique décrit l'utilisateur des jointures de liste et des projections de champs dans les requêtes et les vues définies de Langage CAML (Collaborative Application Markup Language).

Jointures et projections en mode liste

Un affichage sous forme de liste peut inclure des champs provenant d’autres listes qui ont été jointes à la liste principale. L’élément CAML View implémente cette fonctionnalité par le biais de ses éléments enfants Joins et ProjectedFields, qui sont représentés dans le modèle objet par les propriétés Joins et ProjectedFields de l’objet SPView. (L’objet SPQuery possède des propriétés ayant les mêmes noms. Consultez Jointures et projections dans les requêtes pour plus d’informations.)

Jointures de liste dans les affichages

L'élément Joins contient un ou plusieurs éléments Join. Chacun de ces éléments crée une jointure interne ou une jointure externe entre deux listes. Une de ces jointures au moins doit émaner de la liste parent de l'affichage, appelée liste principale, et d'une autre liste, appelée liste étrangère. Mais il peut y avoir des jointures supplémentaires à partir de cette liste étrangère, et ainsi de suite. Il n'existe pas de limite quant au nombre de liens qui peuvent figurer dans une chaîne de jointures, mais le nombre total d'éléments Join, qu'ils constituent des chaînes ou non, ne peut pas dépasser la valeur de la propriété MaxQueryLookupFields de l'objet SPWebApplication contenant la liste principale. La valeur système par défaut est égale à huit. Une liste peut être jointe à elle-même ou à une chaîne de jointures.

Important

Certains impératifs sont à noter lors de la création de jointures de listes. Vous ne pouvez pas joindre deux listes quelconques, indépendamment de leur type. Et si deux listes peuvent être jointes, vous ne pouvez pas utiliser n'importe quel champ principal et étranger comme paire de champs pour la jointure. Le champ de la liste principale doit être un champ de type consultation (Lookup) et il doit consulter le champ dans la liste étrangère. Pour cette raison, toutes les jointures reflètent les relations de consultation entre les listes.

Les balises de l'exemple suivant illustrent un site Web SharePoint Foundation qui héberge un club de parents qui vendent des vêtements enfants d'occasion. Il y a besoin d'un affichage de la liste de commandes Orders qui montre la ville et l'État du membre acheteur (client) ainsi que la ville du membre vendeur (l'expéditeur). Pour implémenter ce scénario, il existe deux chaînes de jointure externe gauche :

  • Commandes à Membres à Cities à States

  • Commandes à Membres à Cities

Notez ce qui suit concernant les balises Joins :

  • L'attribut Type de chaque élément Join peut être « LEFT » ou « INNER ».

  • Comme il y a deux jointures émanant de Commandes à Membres, elles doivent être différenciées. Cela est facilité par l'attribut ListAlias, qui affecte à la liste Membres l'alias « customer » dans al première jointure, mais lui affecte l'alias « shipper » dans la deuxième jointure.

  • Il existe aussi deux jointures émanant de Membres à Villes et leur l'ambiguïté est levée de la même manière.

  • Il n'existe pas d'endroit où un alias de liste est mappé explicitement à une liste. Un mappage n'est pas nécessaire car chaque jointure met en parallèle une relation de champ de recherche existant et la définition du champ de recherche identifie la liste étrangère.

  • Les champs de jointure sont identifiés par une paire d'éléments FieldRef. Le premier représente le champ de recherche (Lookup) dans la liste principale et l'identifie par son nom interne. Il doit avoir un attribut RefType défini sur « Id ». Si la liste principale de la jointure n'est pas la liste parente de l'affichage, alors, elle aussi, est identifiée avec un attribut List défini à son alias. Le deuxième élément FieldRef de chaque paire identifie la liste étrangère, et le champ de clé étrangère, qui doit toujours être le champ Id.

<Joins>
  <Join Type='LEFT' ListAlias='customer'>
    <Eq>
      <FieldRef Name='CustomerName' RefType='Id'/>
      <FieldRef List='customer' Name='ID'/>
    </Eq>
  </Join>

  <Join Type='LEFT' ListAlias='customer_city'>
    <Eq>
      <FieldRef List='customer' Name='CityName' RefType='Id'/>
      <FieldRef List='customer_city' Name='Id'/>
    </Eq>
  </Join>

  <Join Type='LEFT' ListAlias='customer_city_state'>
    <Eq>
      <FieldRef List='customer_city' Name='StateName' RefType='Id'/>
      <FieldRef List='customer_city_state' Name='Id'/>
    </Eq>
  </Join>

  <Join Type='LEFT' ListAlias='shipper'>
    <Eq>
      <FieldRef Name='ShipperName' RefType='Id'/>
      <FieldRef List='shipper' Name='ID'/>
    </Eq>
  </Join>

  <Join Type='LEFT' ListAlias='shipper_city'>
    <Eq>
      <FieldRef List='shipper' Name='CityName' RefType='Id'/>
      <FieldRef List='shipper_city' Name='Id'/>
    </Eq>
  </Join>
</Joins>

Champs projetés dans les affichages

L'élément ProjectedFields crée des champs à partir des listes étrangères de façon qu'ils puissent être utilisés en mode liste. Les champ doivent être également identifiés dans l'élément enfant ViewFields de l'élément View.

Pour poursuivre avec l'exemple du club des parents, le ProjectedFields crée des champs pour la ville du client, l'État du client et la ville de l'expéditeur. Notez ce qui suit concernant ce balisage :

  • Les listes étrangères sont identifiées par leurs alias, comme défini dans l'élément Joins.

  • L'attribut ShowField identifie le champ de la liste étrangère qui est utilisée dans cet affichage.

  • L'attribut Type a toujours la valeur « Lookup ». Pour cette raison, l'attribut Type n'indique pas le type des données du champ comme il le fait généralement dans un élément Field. Quand un élément Field est un enfant de ProjectedFields, Type indique simplement si le Join (dans l'élément Joins sur lequel dépend l'élément ProjectedFields) repose sur une relation de recherche existante entre les listes. Toutes les jointures doivent reposer sur une relation de recherche existante. Consultez ci-dessous la liste des types de champs CAML qui peuvent être des champs projetés.

<ProjectedFields>
  <Field 
    Name='CustomerCity'
    Type='Lookup'
    List='customer_city'
    ShowField='Title'/>
  <Field 
    Name='CustomerCityState'
    Type='Lookup'
    List='customer_city_state'
    ShowField='Title'/>
  <Field 
    Name='ShipperCity'
    Type='Lookup'
    List='shipper_city'
    ShowField='Title'/>
</ProjectedFields>

Seuls les types de champs suivants peuvent être inclus dans un élément ProjectedFields :

  • Calculé (considéré comme du texte brut)

  • ContentTypeId

  • Counter

  • Devise

  • Date et heure

  • Guid

  • Entier

  • Note (une seule ligne)

  • Nombre

  • Texte

Comme indiqué ci-dessus, il est également nécessaire que les champs créés dans l'élément ProjectedFields soient spécifiées dans l'élément ViewFields. Le balisage suivant continue l'exemple.

<ViewFields>
  <FieldRef Name='CustomerCity'/>
  <FieldRef Name='CustomerCityState'/>
  <FieldRef Name='ShipperCity'/>
</ViewFields>

Jointures et projections dans les requêtes

Les champs de jointures et de projections peuvent également être utilisés dans les requêtes CAML. Dans ce cas, également, les champs de jointures et de projections sont définis avec les éléments Joins et ProjectedFields. Cependant, les éléments ne sont pas des enfants de l'élément Query. Ce sont des balises XML indépendantes qui forment la valeur des propriétés SPQuery.Joins et SPQuery.ProjectedFields de l'objet SPQuery représentant la requête.

Il est généralement préférable d’utiliser LINQ to SharePoint Provider pour interroger les listes SharePoint Foundation avec le code serveur. Comme CAML possède les éléments Joins et ProjectedFields, le fournisseur LINQ à SharePoint Provider, qui convertit les requêtes LINQ en requêtes CAML, peut entièrement prendre en charge les opérateurs LINQ join (Join dans Visual Basic) et select (Select dans Visual Basic). Si votre code est destiné à s’exécuter sur des clients, nous vous recommandons d’interroger à l’aide de Effectuer des requêtes sur SharePoint Foundation avec ADO.NET Data Services.

Si vous voulez créer des requêtes CAML directement et définir explicitement les propriétés pertinentes d'un objet SPQuery, vous devez envisager utiliser un outil pour générer les requêtes. Pour accéder à ces outils, rendez-vous sur www.bing.com et recherchez « CAML query tool » sans les guillemets. Après le lancement de Microsoft SharePoint Foundation 2010, les outils prenant en charge la génération des éléments Joins et ProjectedFields peuvent ne pas être disponibles immédiatement.

L'exemple suivant illustre une requête qui retourne toutes les commandes de la liste Orders où la liste du client est Londres. L'exemple suppose que la liste Commandes a un champ CustomerName qui consulte la liste Client et que cette dernière liste a un champ CityName qui consulte la liste Villes.

La requête nécessite une jointure de Commandes à Clients et de Clients à Villes, ce qui fait que la valeur de la propriété Joins serait comme suit.

<Joins>
  <Join Type=’LEFT’ ListAlias=’customers’>
    <Eq>
      <FieldRef Name=’CustomerName’ RefType=’Id’ />
      <FieldRef List=’customers’ Name=’ID’ />
    </Eq>
  </Join>

  <Join Type=’LEFT’ ListAlias=’customerCities’>
    <Eq>
      <FieldRef List=’customers’ Name=’CityName’ RefType=’Id’ />
      <FieldRef List=’customerCities’ Name=’ID’ />
    </Eq>
  </Join>
</Joins>

Dans la mesure où la section Where de notre requête va tester la ville du client, nous devons créer un champ CustomerCity. Partant, la valeur de ProjectedFields est comme suit.

<ProjectedFields>
  <Field
    Name=’CustomerCity’
    Type=’Lookup’
    List=’customerCities’
    ShowField=’Title’ />
</ProjectedFields>

Ensuite, nous devons rendre le champ disponible en ajoutant une référence le concernant à l'élément ViewFields. Par conséquent, la valeur de la propriété ViewFields est comme suit.

<ViewFields>
  <FieldRef Name='CustomerCity'/>
</ViewFields>

Enfin, la propriété Query est définie comme suit.

<Query>
  <Where>
    <Eq>
      <FieldRef Name='CustomerCity'/>
      <Value Type='Text'>London</Value>
    </Eq>
  </Where>
</Query>

Jointures implicites sans élément Joins

Nous vous recommandons d'utiliser un élément Joins explicite quand votre requête CAML implique une jointure de listes à des fins de maximisation de la lisibilité de vos balises. Ce faisant, vous maximisez également la chance de rendre les balises de votre requête compatibles avec les versions futures de SharePoint Foundation. Il existe, cependant, une façon de prendre en charge une jointure implicite de deux listes sans utiliser un élément Joins. Vous pouvez simplement créer un élément ProjectedFields comme décrit ci-dessus, sauf que l'élément enfant Field a un attribut à la place FieldRef de l'attribut List. FieldRef identifie simplement la colonne de recherche (Lookup) dans la liste source. Quand l'élément ProjectedFields a aussi un attribut FieldRef à la place de l'attribut List, son attribut Name doit recevoir une valeur arbitraire qui est différente de toute colonne dans la liste source. (Là encore, dans ce balisage, il n'est pas nécessaire d'identifier la liste cible car elle est spécifiée dans la configuration de la relation Lookup.)

Par exemple, en tenant compte des mêmes listes et relations de recherche de la section précédente, vous avez la requête et l'élément ViewFields suivants.

<Query>
  <Where>
    <Eq>
      <FieldRef Name='CustomerName'/>
      <Value Type='Text'>Hicks, Cassie</Value>
    </Eq>
  </Where>
</Query>

<ViewFields>
  <FieldRef Name='CustomerName'/>
</ViewFields>

Notez que l'élément Where effectue une jointure implicite entre les listes Orders et Customers. Vous pouvez prendre en charge cette requête avec uniquement l'élément ProjectedFields suivant. Nul besoin pour un élément Joins. (Notez que l'attribut Name a reçu un nom arbitraire qui est différent du nom de colonne de recherche réelle qui est spécifiée avec l'attribut FieldRef.)

<ProjectedFields>
  <Field
    Name=’OrderingCustomer’
    Type=’Lookup’
    FieldRef=’CustomerName’
    ShowField=’Title’ />
</ProjectedFields>

Même avec cette technique, il est toujours impératif d'avoir une relation de recherche entre la colonne source et la liste cible. De même, avec cette technique, vous ne pouvez pas chaîner des jointures. Vous ne pouvez pas, par exemple, prendre en charge l'élément Requête de service Web indiqué à la fin de la section précédente. Cette requête réalise une double jointure implicite à partir de Orders vers Customers vers Cities. Une chaîne de jointures nécessite un élément Joins explicite.

Voir aussi

Autres ressources

Gestion des données avec LINQ to SharePoint