Je suis récemment intervenu chez un client qui avait des problèmes de performances sur l’insertion de plus de 2000 entrées dans un liste : la page réalisant l’action tombait en erreur au bout de 8 mn :(

Le code de la page n’avait pas de problèmes fondamentaux : une simple boucle sur un SPList.Items.Add, rien de particulier. Mais c’était pourtant cela le problème : certaines API SharePoint du modèle objet, bien pratiques par ailleurs, ne sont pas assez performantes pour être utilisées pour réaliser du traitement de batch. Il faut descendre plus bas niveau. Pour de la recherche, cela signifie souvent basculer sur du SPQuery ou du CrossListQueryInfo. Et pour de l’insertion, de la modification ou de la suppression, il faut utilser SPWeb.ProcessBatchData. Cette API prend en entrée une liste de commande à exécuter, et renvoie une liste de statuts.

En reprenant un exemple, la syntaxe en entrée donne :

<?xml version="1.0" encoding="UTF-8"?>
<ows:Batch OnError="Continue">
<Method ID="1">
    <SetList>71a9fac3-2e94-4246-8fec-41e30ea65b06</SetList>
    <SetVar Name="Cmd">Save</SetVar>
    <SetVar Name="ID">New</SetVar>
    <SetVar Name="urn:schemas-microsoft-com:office:office#OrderDate">2009-2-21</SetVar>
    <SetVar Name="urn:schemas-microsoft-com:office:office#OrderDateTime">2009-2-21</SetVar>
    <SetVar Name="urn:schemas-microsoft-com:office:office#CustomerID">1;#Cust_1</SetVar>
  </Method>
<Method ID="2">
    <SetList>71a9fac3-2e94-4246-8fec-41e30ea65b06</SetList>
    <SetVar Name="Cmd">Save</SetVar>
    <SetVar Name="ID">3</SetVar>
    <SetVar Name="urn:schemas-microsoft-com:office:office#OrderDate">2009-2-21</SetVar>
    <SetVar Name="urn:schemas-microsoft-com:office:office#OrderDateTime">2009-2-21</SetVar>
    <SetVar Name="urn:schemas-microsoft-com:office:office#CustomerID">1;#Cust_1</SetVar>
  </Method>
<Method ID="3">
    <SetList>71a9fac3-2e94-4246-8fec-41e30ea65b06</SetList>
    <SetVar Name="Cmd">Delete</SetVar>
    <SetVar Name="ID">4</SetVar>
    <SetVar Name="urn:schemas-microsoft-com:office:office#OrderDate">2009-2-21</SetVar>
    <SetVar Name="urn:schemas-microsoft-com:office:office#OrderDateTime">2009-2-21</SetVar>
    <SetVar Name="urn:schemas-microsoft-com:office:office#CustomerID">2;#Cust_2</SetVar>
  </Method>
</ows:Batch>

La première commande créé un nouvel élément dans la liste dont l’identifiant est passé en paramètre. La deuxième modifie un élément existant. La troisième supprime un élément.

Il y a quelques petites astuces à connaître lorsque l’on utilise cette API. L’une des plus épineuse est la gestion des sous-répertoire. La réponse est en fait simple, mais mal documentée : il faut utilisé un sous-noeud owsfileref avec le chemin relatif de l’item à utiliser :

<SetVar Name="owsfileref">/sites/1/docs/codes.txt</SetVar>

Dans le cas de mon client, on est redescendu à 40 s, sans erreurs :)