2009-09-08 8 views
5

Po przeczytaniu Stefan Gossner's post o wyrzucaniu obiektów i tego pytania o Cross method dispose patterns, stwierdziłem, że jestem winny przypadkowego ponownego otwarcia niektórych SPWeb. Wiem na liście Stefana Gossnera, że ​​powinieneś pozbyć się SPWeb po ukończeniu dowolnego obiektu podrzędnego. Jednak w dokumencie microsoft documentation wspomniano o buforowaniu obiektu SPListItemCollection. Czy poniższy kod jest prawidłowy? Czy zwrócony obiekt SPListItemCollection ponownie otworzy obiekt SPWeb? Czy istnieje jakiś sposób, aby powiedzieć na pewno?Czy użycie obiektu SPListItemCollection zwrócony z funkcji ponownie otworzy 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; 
} 

Edit 09.09.09

Mam na myśli głównie do tej części Stefan Grossner's post:

powinny pozbyciem się SPWeb lub SPSite obiekt po ostatnim dostęp do obiekt potomny tego obiektu.

Wierzę, że mówi, że jeśli użyję SPListItemCollection po tym, jak pozbyć się SPWeb, który użyłem, aby go uzyskać ... SPWeb zostanie automatycznie otwarte ponownie.

Odpowiedz

4

Dowiedziałem się po asking Stefan directly, że SPListItemCollection może rzeczywiście ponownie otworzyć SPWeb po pozbyciu się go. Oznacza to, że mój kod zamieszczony powyżej jest NIEPRAWIDŁOWY i mógłbym tylko pozbyć się SPWeb po użyciu składnika SPListItemCollection.

Aktualizacja: Lepiej jest przekonwertować do SPListItemCollection na coś innego i zwrócić je zamiast tego.

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

O ile wiem, odpowiedź brzmi nie, ale chciałbym napisać kod na coś takiego

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

Robiąc to, aby wywołać tę metodę trzeba by wysłać metodę wzdłuż (delegata), która SPListItemCollection powinien być stosowany, przykład:

FetchItems (szt => ....) lub FetchItems (DoStuffWithItems (SPListItemCollection))

+0

Prawdopodobnie mógłbym to zrobić za pomocą Action <>, ale nie sądzę, żeby akcja się kiedykolwiek zmieniła ... Myślę, że to pokonuje cel Akcji <>? Prawdopodobnie wystarczy przenieść cały kod za pomocą SPListItemCollection wewnątrz funkcji GetListItems(), aby być bezpiecznym. –

0

Jeśli mówimy o tym, czy potrzebne jest SPWeb w tym samym zakresie kiedy przejdziesz do używania SPList ItemCollection, myślę, że odpowiedź brzmi "nie".

Na przykład, rutynowo wykonać następujące czynności:

private IEnumerable<SPListItem> AllItems; 

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

a następnie użyć AllItems wszędzie, i to działa dobrze.

Zastanawiasz się, że obsada jest wykonywana, więc mogę użyć Linq na zestawie wyników - znacznie szybciej niż wysłanie zapytania do listy, szczególnie jeśli robisz wiele subselectów na danych.

+0

Niestety, mam dostęp tylko do Visual Studio 2005 i nie sądzę, że będę mógł używać Linq. Podoba mi się twoja metoda zwracania elementów SPListItems.Jednak moje pytanie nie dotyczy tego, czy POTRZEBUJESZ SPWeb, ale czy automatycznie otworzy się kolejna, która będzie musiała zostać usunięta. –

+0

Ahh, o ile mi wiadomo, nie, jeden nie jest tworzony, gdy raz dostaniesz przedmioty, które są samoistne. – Moo

+0

Ponadto, jeśli nie będziesz używać Linq, możesz po prostu przechowywać kolekcję jako SPListItemCollection i zrobić foreach (SPListItem MyItem in ListItems) {} pętla na nich – Moo

Powiązane problemy