SPListからSPListItemを取得します。 非常に高速で非常に遅い

SharePointのWebパーツをプロファイリングするとき、SPListItemCollection.this [Guid]でボトルネックを見つけることに驚きました。実際、主キーであるGuidでリストアイテムを取得すると、大規模なコレクションに多くの時間がかかりました。

このように起こった



var uniqId = new Guid ( /* get GUID somehow */ );

SPList list = /* get list somehow */



SPListItem anItem = list.Items[uniqId];




* This source code was highlighted with Source Code Highlighter .




リストからアイテムを取得する方法は他にありますか?

SPList.GetItemByUniqueId(Guid uniqueId)があります-使用する場合、そのような遅延はありません。 なんで?



リフレクターを使用し、chareponitisをリバースエンジニアリングします...



SPListItemCollection.this [Guid]に表示される内容は次のとおりです。



public SPListItem this [ Guid uniqueId]

{

get

{

this .EnsureListItemsData();

this .EnsureFieldMap();

int iIndex = 0;

int columnNumber = this .m_mapFields.GetColumnNumber( "UniqueId" );

string str2 = uniqueId.ToString( "B" ).ToLower();

while ( true )

{

if (iIndex >= this .m_iRowCount)

{

throw new ArgumentException();

}

string str = (( string ) this .m_arrItemsData[columnNumber, iIndex]).ToLower();

int num3 = SPUtility.StsBinaryCompareIndexOf(str, ";#" );

if ((num3 > 0) && (str.Substring(num3 + 2) == str2))

{

this .EnsureListItemIsValid(iIndex);

if ( this .m_iColection == null )

{

return new SPListItem( this , iIndex);

}

return this .m_iColection.ItemFactory(iIndex);

}

iIndex++;

}

}

}





* This source code was highlighted with Source Code Highlighter .






コレクション全体の内容は要素ごとに並べ替えられ、各要素について、GUIDは指定されたものと一致します。 コレクションが大きいほど、作業時間が長くなります。



そして今GetItemByUniqueId:

public SPListItem GetItemByUniqueId( Guid uniqueId)

{

SPQuery query = new SPQuery();

query.Query = "<Where><Eq><FieldRef Name=\"UniqueId\"></FieldRef><Value Type=\"Guid\">" + uniqueId.ToString( "B" ) + "</Value></Eq></Where>" ;

query.ViewAttributes = "Scope=\"RecursiveAll\" ModerationType=\"Moderator\"" ;

query.MeetingInstanceId = -2;

query.QueryOpt = SPQuery.SPQueryOpt.None | SPQuery.SPQueryOpt.UniqueId;

SPListItemCollection items = this .GetItems(query);

if (items.Count != 0)

{

return items[0];

}

while (!( this .ID == this .Lists.Web.UserInfoListId))

{

throw new ArgumentException();

}

throw new ArgumentException(SPResource.GetString( "CannotFindUser" , new object [0]));

}





* This source code was highlighted with Source Code Highlighter .






ここでは、SPQueryを使用して、コレクションを列挙せずにレコード自体を直接取得します。



結論:大規模なリストでは、SPList.Items [Guid]を使用すると長く、非生産的です。 SPList.getItemByUniqueId(Guid)の方が望ましい;



UPDvlademに感謝-テーマKBへの便利なリンク-http : //msdn.microsoft.com/en-us/library/bb687949.aspx



All Articles