SharePoint 2007 : Extension Method (AddItems)

Lors des précédent billets sur les extensions de méthode, je vous ai parlé d'un manière plus intuitive de récupèrer une SPList (mais potentiellement SPWeb, SPUser, etc...), je vous ai aussi montrer comment gagner énormément de temps lors de la suppression d'élements dans vos liste et finalement, pour boucler la boucle, je vais vous montrer aujourd'hui une méthode qui vous permet d'ajouter simplement des éléments dans une liste en évitant la méthode classique qui peut sembler rébarbative:

using (SPSite site = new SPSite("http://localhost"))

{

    using (SPWeb web = site.RootWeb)

    {

        SPList listAnnonces;

        Stopwatch stopWatch = new Stopwatch();

 

        //So easy to get a SPList like that.

        if (web.Lists.TryGet(STR_Annonces, out listAnnonces))

        {

            Console.WriteLine("List : {0} Add via Classic Method\r\n\tBefore \tNB Items : {1}", STR_Annonces, listAnnonces.ItemCount);

            Random rnd = new Random();

 

            SPListItemCollection listAnnoncesItems = listAnnonces.Items;

            //Generate a paragraph of Lipsum from http://code.google.com/p/nlipsum/

            string bodyContent = LipsumGenerator.Generate(1);

            stopWatch.Start();

 

            for (int i = 0; i < 100; i++)

            {

                SPListItem item = listAnnoncesItems.Add();

                item["Title"] = rnd.Next();

                item["Body"] = bodyContent;

                item["Expires"] = DateTime.Now;

                item.Update();

            }

            listAnnonces.Update();

 

            stopWatch.Stop();

 

            Console.WriteLine("\tAfter \tNB Items : {1}\tElapsed : {2} Msec",

                STR_Annonces,

                listAnnonces.ItemCount,

                stopWatch.ElapsedMilliseconds);

 

            stopWatch.Reset();

...

Et encore ici, je triche un peu en utilisant ma méthode d'extension qui me permet de simplifier l'accès à la liste.

Maintenant si je compare en utilisant l'extension de méthode AddItems sur une SPList:

using (SPSite site = new SPSite("http://localhost"))

{

    using (SPWeb web = site.RootWeb)

    {

        SPList listAnnonces;

        Stopwatch stopWatch = new Stopwatch();

 

        //So easy to get a SPList like that.

        if (web.Lists.TryGet(STR_Annonces, out listAnnonces))

        {

            Console.WriteLine("List : {0} Add via Extension Method\r\n\tBefore \tNB Items : {1}", STR_Annonces, listAnnonces.ItemCount);

 

            //Create the Data you will insert in each Items

            Dictionary<string, string> metadata = new Dictionary<string, string>();

            metadata.Add("Title", null);

            //Generate a paragraph of Lipsum from http://code.google.com/p/nlipsum/

            metadata.Add("Body", LipsumGenerator.Generate(1));

            string validDateTimeFormat = SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now);

            // We need to insert a valid dateTime with a specific format : 2008-06-01T14:02:08Z

            metadata.Add("Expires", validDateTimeFormat);

 

            stopWatch.Start();

            listAnnonces.AddItems(100, metadata, true);

            stopWatch.Stop();

 

            Console.WriteLine("\tAfter \tNB Items : {1}\tElapsed : {2} Msec", STR_Annonces,

                listAnnonces.ItemCount,

                stopWatch.ElapsedMilliseconds);

        }

 

         //Another Example with a different format (URL)

        if (web.Lists.TryGet(STR_Liens, out listAnnonces))

        {

            Console.WriteLine("List : {0}, Number of Items  : {1}", STR_Liens, listAnnonces.ItemCount);

 

            Dictionary<string, string> metadata = new Dictionary<string, string>();

            metadata.Add("URL", http://localhost, Home);

            metadata.Add("Comments", LipsumGenerator.Generate(1));

 

            listAnnonces.AddItems(10, metadata, true);

 

            Console.WriteLine("List : {0}, Number of Items  : {1}", STR_Liens, listAnnonces.ItemCount);

        }

    }

}

Au final, ces appels nous donne en sortie la création de 100 éléments chacun, voyons la différence en terme de rapidité.

diff_classic_and_extension

Encore une fois, c'est l'utilisation de ProcessBatchData qui nous permet d'avoir cette différence de performance. L'utilisation en elle-même n'est pas des plus aisée, d'où l'intérêt de l'encapsuler dans cette extension de méthode :

/// <summary>

/// Adds Item to the selected List, will use the metadata to insert data into Columns

/// Will throw an SPException if an error occurs or If Metadata is null

/// </summary>

/// <param name="list">The list.</param>

/// <param name="nbItems">The Number of items to create</param>

/// <param name="metadata">The metadata used to insert data into Items.</param>

public static void AddItems(this SPList list, int nbItems, Dictionary<string, string> metadata, bool forceUpdate)

{

    if (metadata == null)

        throw new SPException("AddItems : Metadata can't be null");

 

    // Adding 0 items...

    if (nbItems == 0)

        return;

 

    StringBuilder sbAdd = new StringBuilder(100 * nbItems);

    sbAdd.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Batch OnError=\"Return\">");

    Guid listGuid = list.ID;

    for (int i = 0; i < nbItems; i++)

    {

        sbAdd.AppendFormat("<Method ID=\"{0},Save\"><SetList>{1}</SetList><SetVar Name=\"ID\">New</SetVar><SetVar Name=\"Cmd\">Save</SetVar>", i, listGuid);

        foreach (KeyValuePair<string, string> pair in metadata)

        {

            string value = pair.Value;

            //Just in case, i wan't a field with pseudo random content, should propably improve this.

            if (value == null)

                value = rnd.Next().ToString();

            sbAdd.AppendFormat("<SetVar Name=\"urn:schemas-microsoft-com:office:office#{0}\">{1}</SetVar>", pair.Key, value);

        }

        sbAdd.Append("</Method>");

    }

    sbAdd.Append("</Batch>");

 

    SPWeb oListParentWeb = list.ParentWeb;

    string batchResult = oListParentWeb.ProcessBatchData(sbAdd.ToString());

    //Dispose !!! http://blogs.msdn.com/rogerla/archive/2008/02/12/sharepoint-2007-and-wss-3-0-dispose-patterns-by-example.aspx

    oListParentWeb.Dispose();

 

    if (forceUpdate)

        list.Update();

 

    string errorMessage = ResultFromBatchCommand(batchResult);

    if (errorMessage != String.Empty)

        throw new SPException(errorMessage);

}

Si vous avez d'autre idées de méthodes ou d'optimisations, n'hésitez à pas à laisser un commentaire.

<Philippe/>

Publié lundi 2 juin 2008 10:30 par phil
Classé sous , , , ,
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

About phil

Philippe Sentenac est Consultant SharePoint à Wygwam en région Parisienne. Il intervient essentiellement sur des missions liées à SharePoint (2007 et 2010 ) mais aussi autour du Web 2.0. Plus généralement, il s'intéresse à l'ASP.Net (MVC) , à Silverlight, et à tout ce qui est orienté Web en rapport avec les nouvelles technologies, qu'il pratique depuis 2006. Féru de développement, il est passionné par les problématiques de méthodologies et d'industrialisation du développement.

Les 10 derniers blogs postés

- [SharePoint] Roadshow Microsoft SharePoint Solutions par Le petit blog de Pierre / Pierre's little blog le il y a 3 heures et 6 minutes

- Les actualités de c2i.fr : 28 Mai - 3 Juin par Richard Clark le il y a 22 heures et 3 minutes

- [Office 365] Utiliser le modèle objet client SharePoint en PowerShell vers SharePoint Online par Blog de SPBrouillet (Pierrick BROUILLET) le 06-03-2012, 19:07

- Roslyn fluent APIs: RoslynHelper NuGet package par Matthieu MEZIL le 05-31-2012, 01:24

- Pour rappel ! Les spécifications des protocoles Office et SharePoint sont disponibles sur MSDN par Julien Chable le 05-29-2012, 12:33

- Joyeux anniversaire Nix par The diary of EBArtSoft le 05-29-2012, 01:00

- Imagine Cup 2012, Make a Sign en finale par Le Blog (Vert) d'Arnaud JUND le 05-23-2012, 12:57

- Kinect 1.5 is out ! par Cyril Sansus le 05-21-2012, 17:47

- Les actualités de la semaine sur c2i.fr (14 mai - 20 mai) par Richard Clark le 05-21-2012, 08:50

- Reactive Extensions : Consommer des services avec Rx Partie 3, les pièges à éviter par Léonard Labat le 05-20-2012, 23:45