2011-08-25 21 views
1

我有一個77 SPListItem對象的集合。這些對象可以隱含對其他對象的遞歸引用*。目前這個層次結構中有4個層次。需要幫助解決我遇到的Linq-to-Objects查詢性能問題?

我遇到的問題是,當我得到層次結構中較深的項目時,檢索它們需要很長的時間。

zeroth: nearly instant 
first: 2 seconds 
second: 20 seconds 
third: goes for about a minute and then times out 

這是場中SPListItem對象的結構::一次我在每個級別看到

ID 
Title 
ParentId //recursive field 

這是我使用來獲得在每個級別的SPListInformation的代碼:

SPList navList = SPContext.Current.Web.Lists["NavStructure"]; 

//Get items that have no parent 
var zero = from n in navList.Items.Cast<SPListItem>()             
      where ((SPFieldLookupValueCollection)n["Parent"]).Count == 0        
      select new { ID = n.ID, Title = n.Title }; 

//Get first level items 
var first = from n in navList.Items.Cast<SPListItem>() 
      from z in zero 
       where ((SPFieldLookupValueCollection)n["Parent"]).Select(t => t.LookupId).Contains(z.ID) 
      select new { ID = n.ID, Title = n.Title, ParentId = z.ID}; 
lv_First.DataSource = first.ToList(); 
lv_First.DataBind(); 

//Get second level items 
var second = from n in navList.Items.Cast<SPListItem>() 
      from z in first 
       where ((SPFieldLookupValueCollection)n["Parent"]).Select(t => t.LookupId).Contains(z.ID) 
      select new { ID = n.ID, Title = n.Title, ParentId = z.ID}; 
lv_Second.DataSource = second.ToList(); 
lv_Second.DataBind(); 

//Get third level items 
var third = from n in navList.Items.Cast<SPListItem>() 
      from z in second 
      where ((SPFieldLookupValueCollection)n["Parent"]).Select(t => t.LookupId).Contains(z.ID) 
      select new { ID = n.ID, Title = n.Title, ParentId = z.ID}; 
lv_Third.DataSource = third.ToList(); 
lv_Third.DataBind(); 

任何人都可以看到我在這裏做的事情,可能會導致我看到的長時間運行?

如果有人希望看到數據只是讓我知道。我離開了它,因爲它會有點冗長。 *當我說「隱含的遞歸引用」時,我的意思是每個SPListItem對象中都有一個成員可以包含一個ID,並且這個ID引用列表中的另一個對象,但是這種關係不會被強制執行。

回答

5

好吧,你執行first查詢每個navListsecond ...每一次你,你再執行在navListzero查詢每個項目執行first查詢。 third全部爲爲每個項目。

只需在每個查詢結尾添加對ToList的調用,就可能顯着提高速度。

目前還不太清楚你想要做什麼,但感覺好像你可以使用DictionaryLookup而不是每次想要找到某個東西時迭代整個集合。

+0

最後,我使用這些數據來創建分層導航欄。這些數據集中的每一個最終都會呈現給層次結構中相應的div。我會看看使用字典或查找,看看這些是否是一個選項。 –

+0

是的,將'ToList'移動到查詢本身而不是DataSource使得整個事情幾乎是即時的。我仍然會檢查LookUp,它看起來很有希望。 –

2

由於您直接使用IEnumerable,因此您正在重新枚舉每次傳遞之前的所有枚舉。我建議存儲由ToList()創建的列表並在隨後的調用中使用它。

+0

良好的通話,這使得它幾乎即時。謝謝! –