2009-09-08 10 views
5

Después de leer Stefan Gossner's post por la eliminación de objetos y de esta pregunta acerca de Cross method dispose patterns, descubrí que yo era culpable de reabrir accidentalmente algunos SPWebs. Sé en la publicación de Stefan Gossner que menciona que debe deshacerse de un SPWeb después de que haya terminado con cualquier objeto secundario. Sin embargo, el microsoft documentation menciona el almacenamiento en memoria caché del objeto SPListItemCollection. Es el siguiente código correcto? ¿Volvería la SPListItemCollection devuelta a abrir un objeto SPWeb? ¿Hay alguna manera de decirlo con certeza?¿El uso de un SPListItemCollection de regresar de una función de reabrir el 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; 
} 

Editar 09/09/09

Me refiero principalmente a esta parte de Stefan Grossner's post:

Debe disponer de un SPWeb o SPSite objeto después del último acceso a una objeto secundario de este objeto.

creo que lo que está diciendo es que si uso el SPListItemCollection después de disponer de los SPWeb que utiliza para conseguirlo ... el SPWeb se volverá a abrir automáticamente.

Respuesta

4

Descubrí después de asking Stefan directly que SPListItemCollection puede reabrir el SPWeb después de deshacerse de él. Esto significa que el código escrito arriba es incorrecta y que sólo sería capaz de disponer de la SPWeb después de usar el SPListItemCollection.

Actualización: Es mejor para convertir a la SPListItemCollection a otra cosa y volver en su lugar.

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

Por lo que yo sé la respuesta es no, pero yo hubiera escrito el código algo así como

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

Al hacer esto, llamar a este método lo que se necesita para enviar un método largo (delegado) que la SPListItemCollection se debe utilizar para, un ejemplo:

FetchItems (artículos => ....) o FetchItems (DoStuffWithItems (SPListItemCollection))

+0

probablemente podría hacerlo utilizando Acción <>, pero no creo que la acción podría cambiar nunca ... Creo que contradice el objetivo de la acción <>? Probablemente sólo hay que mover todo el código utilizando el SPListItemCollection interior de las GetListItems() la función sólo para estar seguro. –

0

Si usted está hablando acerca de si necesita un SPWeb en el mismo ámbito cuando llegas a utilizar el SPList ItemCollection, creo que la respuesta es no.

Por ejemplo, rutinariamente hacer lo siguiente:

private IEnumerable<SPListItem> AllItems; 

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

y luego utilizo AllItems por todo el lugar, y funciona bien.

En caso que usted se preguntan, el reparto se hace para que pueda utilizar LINQ en el conjunto de resultados - mucho más rápido que enviar una consulta a la lista, especialmente si usted está haciendo múltiples subselects en los datos.

+0

Por desgracia, sólo tengo acceso a Visual Studio 2005 y no creo que voy a ser capaz de utilizar LINQ. Me gusta su método de devolver los SPListItems.Sin embargo, mi pregunta no es si NECESITA un SPWeb, sino si se abrirá otro automáticamente que tendrá que eliminarse. –

+0

Ahh, hasta donde yo sé, no, no se crea una, ya que una vez que obtienes los elementos, todos son autosuficientes. – Moo

+0

Además, si no va a utilizar Linq, podría simplemente almacenar la colección como SPListItemCollection y hacer un foreach (SPListItem MyItem en ListItems) {} loop en ellos – Moo

Cuestiones relacionadas