2009-09-08 65 views
5

在閱讀Stefan Gossner's post關於處置對象和關於Cross method dispose patterns的這個問題後,我發現我意外地重新打開了一些SPWebs。我知道在Stefan Gossner的帖子中他提到你應該在完成任何子對象之後處置SPWeb。但是,microsoft documentation提到緩存SPListItemCollection對象。以下代碼是否正確?返回的SPListItemCollection會重新打開一個SPWeb對象嗎?有什麼方法可以肯定嗎?將使用從函數返回的SPListItemCollection重新打開SPWeb?

// is this correct???? 
private SPListItemCollection GetListItems() 
{ 
    SPListItemCollection items = null; 
    try 
    { 
     using (SPSite site = new SPSite(GetListSiteUrl())) 
     { 
      using (SPWeb web = site.OpenWeb()) 
      { 
       // retrieve the list 
       SPList list = web.Lists[_ListName]; 

       // more code to create the query... 
       items = list.GetItems(query); 
      } 
     } 
    } 
    catch (Exception e) 
    { 
     // log error 
    } 
    return items; 
} 

編輯09/09/09

我主要指的Stefan Grossner's post這一部分:

你應該到上次訪問後處置一個的SPWeb或SPSite 對象 此對象的子對象。

我相信他所說的是,如果我在處理SPWeb時使用了SPListItemCollection,那麼我將會自動重新打開SPWeb。

回答

4

我發現asking Stefan directly之後,SPListItemCollection確實可以在您處置它之後重新打開SPWeb。這意味着我上面發佈的代碼是不正確的,我只能在使用SPListItemCollection之後處理SPWeb。

更新:最好將SPListItemCollection轉換爲別的東西,然後返回。

private DataTable GetListItems() 
{ 
    DataTable table = null; 
    try 
    { 
     SPListItemCollection items = null; 
     using (SPSite site = new SPSite(GetListSiteUrl())) 
     { 
      using (SPWeb web = site.OpenWeb()) 
      { 
       // retrieve the list 
       SPList list = web.Lists[_ListName]; 

       // more code to create the query... 
       items = list.GetItems(query); 

       // convert to a regular DataTable 
       table = items.GetDataTable(); 
      } 
     } 
    } 
    catch (Exception e) 
    { 
     // log error 
    } 
    return table; 
} 
1

據我知道答案是否定的,但我會寫的代碼像

private void FetchItems(Action<SPListItemCollection> action) 
{ 
    using(...) 
    { 
     var items = list.GetItems(query); 
     action(items); 
    } 
} 

通過這樣做,調用這個方法,你需要發送沿(代表)的一種方法,的SPListItemCollection應該用於,一個例子:

FetchItems(項=> ....)或FetchItems(DoStuffWithItems(SPListItemCollection))

+0

我可以使用Action <>來實現它,但我不認爲這個動作會改變......我認爲這會破壞Action <>的目的?我可能只需要使用GetListItems()函數內部的SPListItemCollection來移動所有代碼,以確保安全。 – 2009-09-08 19:49:45

0

如果要談論是否需要一個的SPWeb在同一範圍內當你開始使用SPList時ItemCollection,我認爲答案是否定的。

例如,我經常做到以下幾點:

private IEnumerable<SPListItem> AllItems; 

    public void GetItems() 
    { 
     var results = SPContext.Current.Web.Lists[ListName].Items.Cast<SPListItem>(); 
     this.AllItems = results; 
    } 

,然後我用AllItems所有的地方,並能正常工作。

因爲想知道轉換是否完成,所以我可以在結果集上使用Linq - 比向列表提交查詢要快得多,尤其是如果您要對數據執行多個子查詢。

+0

不幸的是,我只能訪問Visual Studio 2005,我不認爲我能夠使用Linq。我喜歡你返回SPListItems的方法。但是,我的問題不是你是否需要一個SPWeb,而是另一個是否會自動打開,需要處理。 – 2009-09-09 13:40:59

+0

啊,就我所知,不,一旦你得到他們全部包含的物品,就不會創建一個。 – Moo 2009-09-09 16:21:46

+0

另外,如果您不會使用Linq,您可以將該集合存儲爲SPListItemCollection,然後在它們上執行foreach(ListListItems中的SPListItem MyItem){}循環 – Moo 2009-09-09 16:23:15