Best Practice: Don’t Iterate SPListItems for IQueryable Support
I saw this during a code review today. Essentially, to support a LINQ query into a SPListItemCollection, there was an iteration that converted the SPListItemCollection to a typed List collection, the secondary collection subsequently being queried through LINQ. While SPListItemCollection implements IEnumerable it is challenging to use when converting the instance to IQueryable because it will fall back on IEnumerable specification since it simplements IEnumerable, not IQueryable.
The method in question looked like this:
- public static List<SPListItem> ConvertToTypedList(SPListItemCollection collection)
- List<SPListItem> items = new List<SPListItem>();
- foreach (SPListItem item in collection)
- return items;
That iteration IMHO is entirely too expensive for performance reasons because of dual collection builds, and it’s just plain ugly. For each query run, execute collection generation of an already existing collection? No thanks! :)
Instead, just use Cast(), it’s much cleaner and this is the exact situation it is used for. Replicating the intent of the above iteration, I can simply express in the domain terms (via method chaining) the LINQ query (which you can obviously modify with whatever query you like).
- var results = SPContext.Current.Web.Lists["Some List"].Items.Cast<SPListItem>().Select(item => item);
For example, to using a where clause for a specific title:
- var results = SPContext.Current.Web.Lists["Some List"].Items.Cast<SPListItem>().Where(item => item[SPBuiltInFieldId.Title].ToString() == "Title To Search");