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

Leader Technique SharePoint chez Winwise, je m'occupe de missions d'expertise autour de WSS 3.0 et MOSS 2007, tout en me tenant au courant de ce qui se fait autour de Asp.net, Silverlight et des technologies Web by Microsoft en général.

Les 10 derniers blogs postés

- [Silverlight] En attendant Silverlight 2 RTW par Blog Technique d'Audrey PETIT le 10-11-2008, 21:55

- Le nouveau Gojira, c’est pour lundi… par CoqBlog le 10-11-2008, 01:18

- SharePoint : nouvel article sur la mise en place des Scopes dans MOSS Searchs par Blog Technique de Romelard Fabrice le 10-10-2008, 17:52

- Hello CS par Le Blog de julz le 10-10-2008, 12:26

- MSDN/TechNet/Microsoft Days Tour 2008 à Lille les 13 et 14 Octobre ! par RedoBlog - The .NET Gentleman !!! le 10-10-2008, 09:35

- MVC Pratique #07 - Un projet concret et le transfert des objets avec les ModelBinders par #Rui le 10-09-2008, 23:39

- SQL Server 2008 : Certifié - TS Admin (70-432) par SQL Server vu par Christian Robert le 10-09-2008, 10:58

- [WPF] Comment changer la couleur utilisée pour sélectionner les éléments d’un ItemsControl ? par Thomas Lebrun le 10-09-2008, 10:49

- Hello World! par Hamid's Place le 10-08-2008, 23:38

- SQL Profiler - Configuration pour un développeur - tracer les requêtes SQL de votre application par Atteint de JavaScriptite Aiguë [Cyril Durand] le 10-08-2008, 15:52