Showing posts with label SharePoint. Show all posts
Showing posts with label SharePoint. Show all posts

Wednesday, October 14, 2009

Get SPListItem from SPList

Working with SPList was found that upon receipt of a list item on Guid of SPListItemCollection.this [Guid] took a lot of time on a large collection. 
It looked like this:



  1. var uniqId = new Guid(/* get GUID somehow */);
  2. SPList list = /* get list somehow */;
  3. SPListItem anItem = list.Items[uniqId];
* This source code was highlighted with Source Code Highlighter.

But it turns out, there is another way to get a list item SPList.GetItemByUniqueId(Guid uniqueId). Using this method does not arise for the delay in large collections. To determine the differences we use the reflector, and see how to implement a method to obtain an element in the collection for SPListItemCollection in Microsoft.SharePoint.dll. That's what we see in SPListItemCollection.this[Guid]:



  1. public SPListItem this[Guid uniqueId]
  2. {
  3.  get 
  4.  { 
  5.   this.EnsureListItemsData(); 
  6.   this.EnsureFieldMap(); 
  7.   int iIndex = 0; 
  8.   int columnNumber = this.m_mapFields.GetColumnNumber("UniqueId"); 
  9.   string str2 = uniqueId.ToString("B").ToLower(); 
  10.   while (true) 
  11.   {  
  12.    if (iIndex >= this.m_iRowCount)  
  13.    {  
  14.     throw new ArgumentException();  
  15.    }  
  16.    string str = ((string) this.m_arrItemsData[columnNumber, iIndex]).ToLower();  
  17.    int num3 = SPUtility.StsBinaryCompareIndexOf(str, ";#");  
  18.    if ((num3 > 0) && (str.Substring(num3 + 2) == str2))  
  19.    {  
  20.     this.EnsureListItemIsValid(iIndex);  
  21.     if (this.m_iColection == null)  
  22.     {   
  23.      return new SPListItem(this, iIndex);  
  24.     }  
  25.     return this.m_iColection.ItemFactory(iIndex);  
  26.    }  
  27.    iIndex++; 
  28.   } 
  29.  }
  30. }
* This source code was highlighted with Source Code Highlighter.

As we can see the contents of the entire collection moves an element by element, each element is calculated with a given match GUID'a. More collection - the longer work. 

And now look at the implementation of the method GetItemByUniqueId for SPList:



  1. public SPListItem GetItemByUniqueId(Guid uniqueId)
  2. {
  3.  SPQuery query = new SPQuery();
  4.  query.Query = "<Where><Eq><FieldRef Name=\"UniqueId\"></FieldRef><Value Type=\"Guid\">" + uniqueId.ToString("B") + "</Value></Eq></Where>";
  5.  query.ViewAttributes = "Scope=\"RecursiveAll\" ModerationType=\"Moderator\"";
  6.  query.MeetingInstanceId = -2;
  7.  query.QueryOpt = SPQuery.SPQueryOpt.None | SPQuery.SPQueryOpt.UniqueId;
  8.  SPListItemCollection items = this.GetItems(query);
  9.  
  10.  if (items.Count != 0)
  11.  {
  12.   return items[0];
  13.  }
  14.  
  15.  while (!(this.ID == this.Lists.Web.UserInfoListId))
  16.  {
  17.   throw new ArgumentException();
  18.  }
  19.  throw new ArgumentException(SPResource.GetString("CannotFindUser", new object[0]));
  20. }
* This source code was highlighted with Source Code Highlighter.

Here, using SPQuery, we obtain directly the very record without sorting the collection. 
Conclusion: The use of large lists SPList.Items[Guid] - long, unproductive. Better to use SPList.getItemByUniqueId(Guid);