Never use SPList.Items.Add because this approach gets all items in the list before adding a new SPListItem. Use the following method instead, which does not preload the list items:
1: /// <summary>
2: /// More efficient way of adding an item to a list.
3: /// </summary>
4: /// <remarks>
5: /// GetItems with a query is faster than calling the OM to get all items.
6: /// This is because the SPListItemCollection is created without loading all the
7: /// data until the first query request. Whereas SPList.Items loads all the data
8: /// at construction.
9: /// </remarks>
10: /// <param name="list">List.</param>
11: /// <returns>List Item Added.</returns>
12: public static SPListItem OptimizedAddItem(SPList list)
13: {
14: const string EmptyQuery = "0";
15: SPQuery q = new SPQuery {Query = EmptyQuery};
16: return list.GetItems(q).Add();
17: }
Got any metrics on that? I can see what you’re saying, but I was wondering if you’d built a console app or anything to generate some timings. It seems a decidedly non-intuitive way of adding a list item!
The only problem that I see with your approach is that this will fire any alerts, list handlers and workflows (that are programmed to fire automatically on create new or update list item events).
I guess any developers planning on using the above approach should handle the issues that may result.
Andy,
I don’t have metrics to hand, but I did perform a study when I worked with a client, and the optimized version made significant difference in situations where we added lots of list items to lists.
The bigger culprits are SPList.Items.Count, which I see all the time (especially in list iterators), which can be replaced with SPList.ItemCount.
R.
Saurabh,
Quote me if I’m incorrect, but won’t SPList.Items.Add also fire events?
R.
Hi Rob,
SPList.Items.Add will fire events but in that case hopefully all the necessary column fields will be populated (e.g. Title), so any alert or workflow that get created will have all the information they need.
The only reason I bring it up is because in my experience, with such an approach email alerts will still be sent out without any information (other than the List Item ID). So it is something to be aware of.
~
P.S. – Nice blog. It is very well organized and has extremely useful content.
Ah! So that’s why they have them! Always did wonder why the separate ItemCount – always figured it was just a shortcut… …but it makes sense now!
Methinks I’ll have to go tell the rest of the team…
Pingback: SharePoint Document Library and List – File Upload « Karthikeyan K’s Blog
Some comments on MSDN’s SharePoint Best Practices page were complaining that the SPListItem.AddItem() method was missing.
http://msdn.microsoft.com/en-us/library/bb687949.aspx
I let them in on your helpful code here (re-cast as an extension method). Thanks for making it available.
Cheers!
Pingback: #30 Sharepoint: Accessing a Site Collection within a Workflow and updating a list « Integration Points
The syntax of
SPQuery q = new SPQuery {Query = EmptyQuery};
does not work in Visual Studio 2005 and .NET2.0
How is the correct syntax for those VS2005?
Thanks.
SPQuery q = new SPQuery();
Query = EmptyQuery;
Object inline initialization is part of .NET 3.0 and Visual Studio 2008.
Pingback: Random things I learnt doing a code review » Andy Burns’ SharePoint Blog
Pingback: List Item Add Using SPQuery « Sladescross's Blog
Very helpful post. Thanks.
We are using this solution, but we’ve noticed a problem.
The case:
OwnFolder is custom type inherited from SPFolder.
ItemUpdated event handler is attached to OwnFolder’s ItemUpdated. We want on moderation status change (inside ItemUpdated event) to do something to the items inside the folder. But when the folder was created using the AddItem on moderation status change the code inside ItemUpdated is not executed. All other events are executed correctly except this one.
We have verified that when the folder is created through list.Items.Add(..) the problem is not verified.
How we create:
Creating SPFolder using AddItem and changing the content type to OwnFolder. Like this:
SPListItem item = GetEmptyItems(list).Add(folderUrl, fsoType, fsoName);
item.SystemUpdate(false);
item[SPBuiltInFieldId.ContentTypeId] = OwnFolderContentTypeId;
item.SystemUpdate(false);
I hope this helps someone as I haven’t found any info on this problem anywhere.
Pingback: Error Logging in SharePoint « SPMatt
Nice trick. Also, do not forget to set the RowLimit=1.
Cheers.