torsdag 27 augusti 2009

A little bit about SPListItemCollection...

Don't:
SPList list = SPContext.Current.Web.Lists["MyList"];
SPListItem item = list.Items.GetItemById(7);
Do:
SPList list = SPContext.Current.Web.Lists["MyList"];
SPListItem item = list.GetItemById(7);

Why?
Using the "Items" field of an SPList will always create an SPListItemCollection and populate it with all items from the database, which can take a long time if the list contains many items.
Calling GetItemById() directly on the SPList does not require this and can finish in a fraction of the time, even for a list with thousands of items.
To go further into this...
If performance is important (or if you are working with lists with many items), you should (or even must) avoid the "Items" field of SPList completely. Instead use SPQuery and SPList.GetItems(SPQuery) to create your own SPListItemCollection, and limit its size by setting these fields on the SPQuery:
- "ViewFields" - specify only the fields you need.
- Row Limit - set the maximum number of items you need
- Query - of course, to make the collection only contain items which you need.

For example,

Don't:
SPListItem item = list.Items.Add(...);
item.Update();
Do:
SPListItem item = list.GetItems(new SPQuery { RowLimit = 0 }).Add(...);
item.Update();
Another example,

Don't:
itemCount = list.Items.Count;
Do:
itemCount = list.GetItems(new SPQquery { ViewFields = "" }).Count;

Much of this is usually not required of course, but for lists which contains hundreds of items the difference will likely be noticable.

By the way, many of the OM methods use SPQuerys "behind the curtain". For example, SPList.GetItemById() creates an SPQuery with RowLimit = 1 and a "where eq" query searching for the specified ID, and the constructor of SPListItemCollection (which for some reason is marked internal) simply just takes an SPList and an SPQuery as parameters.

Hope this is of use to anyone!