Hmm... Permettez-moi de préciser à l'avance que cet article n'a pas beaucoup de signification pratique, donc les étudiants qui veulent savoir comment utiliser quelque chose peuvent appuyer sur Alt + F4 (ou Ctrl + W). Les étudiants qui souhaitent savoir comment fonctionne SharePoint peuvent continuer à faire défiler la page vers le bas.
J'écris actuellement un livre sur le développement de SharePoint 2010 avec KB et j'ai accidentellement découvert cette méthode en étudiant le modèle objet nouvellement ajouté en 2010. Nous savons tous qu'en 2003/2007, la méthode GetItemById de SPList était utilisée pour obtenir des éléments de liste en fonction de l'ID (Quoi, vous n'avez pas entendu parler de cette méthode ? Alors j'ai bien peur que vous ne soyez pas un développeur SharePoint qualifié...). Le nom de cette méthode nouvellement ajoutée est GetItemByIdSelectedFields (une méthode GetItemByIdAllFields est également ajoutée pour l'accompagner, mais celle-ci est tout à fait équivalente à GetItemById, donc plus de bêtises. La définition de la méthode est la suivante :
1 : public SPListItem GetItemByIdSelectedFields (int id, params string[] champs)
Lorsque j'ai vu cela pour la première fois, j'ai immédiatement pensé à la propriété ViewFields de SPQuery. Lors de l'obtention d'une entrée de liste, seuls certains champs spécifiés sont renvoyés pour améliorer l'efficacité. Mais lorsque j'ai écrit un programme console pour tester, j'ai découvert que ce n'était pas ce que j'imaginais. Par exemple, j'ai écrit (cette méthode nécessite d'écrire le nom interne) :
1 : élément SPListItem = spList.GetItemByIdSelectedFields(1, "Titre", "Créé"); 2 : Console.WriteLine(item["Modifié"]);
Ce programme n'a en fait signalé aucune erreur et la valeur modifiée a été renvoyée normalement, je l'ai donc essayé. Il y avait en fait 50 champs dans une liste personnalisée dont les valeurs étaient renvoyées normalement, mais tous les éléments de requête, utilisateurs et groupes d'utilisateurs l'étaient. renvoyé normalement. (En fait, il s’agit essentiellement d’un élément de recherche) Aucun n’a été renvoyé.
Poussé par la curiosité (ça ne peut pas encore me tuer), j'ai Reflector regardé le code source de cette méthode :
1 : if(field == null) 2 : { 3 : throw new ArgumentNullException("fields"); 4 : } 5 : 6 : StringBuilder builder = new StringBuilder(); 7 : foreach (string str dans les champs) 8 : 9 : if (str != null) 10 : { 11 : builder.Append("<FieldRef Name="" + str + ""/>" 12 : } 13 : } 14 : 15 : foreach (SPField) ; champ dans this.Fields) 16 : { 17 : bool flag = false ; 18 : foreach (chaîne str2 dans les champs) 19 : { 20 : if (str2 == field.InternalName) 21 : { 22 : flag = true 23 : break; 24 : } 25 : } 26 : if (!flag && field.MustFetchByDefault) 27 : { 28 : builder.Append("<FieldRef Name=""); 29 : builder.Append(field.InternalName); 30 : builder.Append(""/>"); 31 : } 32 : } 33 : 34 : return this.GetItemById(id, null, false, builder.ToString());
Concernant le dernier GetItemById, il n'est pas nécessaire de s'y attarder pour l'instant. Sachez simplement qu'il s'agit d'une surcharge de GetItemById, et que son but est de rechercher des éléments. Le dernier paramètre met les champs à obtenir sous forme de CAML. .
Le foreach de la ligne 7 est facile à comprendre. Nous ajoutons les champs dont nous avons besoin ; mais le foreach de la ligne 15 est un peu déroutant au début. Devons-nous également ajouter d'autres champs ? Et quel est le MustFetchByDefault de SPField ? Creusons un peu plus et jetons un coup d'œil :
1 : bool interne MustFetchByDefault 2 : { 3 : get 4 : { 5 : string fieldAttributeValue = this.GetFieldAttributeValue("List"); 6 : if(!string.IsNullOrEmpty(fieldAttributeValue) && 7 : (fieldAttrbuteValue != GlobalList.Docs. ToString())) 8 : { 9 : retourne faux 10 : } 11 : retourne vrai 12 : } 13 : }
Comment déterminer si un champ doit être récupéré ? En jugeant un attribut List du champ, la méthode GetFieldAttributeValue n'est plus postée (sinon elle est soupçonnée de tricher sur le nombre de mots). Bref, il s'agit de trouver une List depuis le nœud Xml similaire à l'attribut SchemaXml (description du champ). ) des propriétés du champ. S'il est trouvé et qu'il ne s'agit pas de GlobalList.Docs (quelque chose de spécial), alors ce champ n'est pas nécessaire. En d'autres termes, je n'ai pas besoin de renvoyer ce champ à l'utilisateur.
Alors, quels champs ont des attributs List dans SchemaXml ? Un champ avec une liste d'attributs ? Découvrez l'article ! Ha, cela a vraiment évité tous les éléments de recherche. (Docs est l'attribut List du champ "path", qui peut avoir une origine particulière)
Nous savons maintenant pourquoi tous les autres champs sont inclus et pourquoi la recherche n'est pas incluse. Mais pourquoi ? Si nous connaissons quelque chose sur la base de données de contenu SharePoint, nous saurons que l'élément de requête stocke en réalité uniquement une valeur d'ID dans la table AllUserData de la base de données de contenu (mais lorsqu'il est extrait à l'aide du modèle objet, il inclut le champ correspondant de l'objet). élément de requête. contenu), ce qui signifie que si vous souhaitez renvoyer la valeur de l'élément de requête, vous devez effectuer des opérations de base de données supplémentaires (telles que rechercher l'élément consulté, renvoyer la valeur du champ correspondant et l'assembler dans "1 ;#Administrateur" ce genre de look fantôme). Plus important encore, si l'élément de recherche est à valeurs multiples, alors l'élément de recherche lui-même est stocké dans une autre table (AllUserDataJunctions), il faut donc beaucoup d'efforts pour le renvoyer. Il y a donc une nouveauté ajoutée en 2010. Si notre liste contient de nombreux éléments de recherche, et que nous ne pouvons en utiliser qu'un ou deux (ou aucun) pour le moment, il semble que l'utilisation de cette méthode puisse effectivement s'améliorer beaucoup. . efficacité.