Compartir a través de


Clase SPFolderHierarchy

Esta clase es una abstracción sobre las carpetas de una lista de SharePoint Server diseñado para evitar las limitaciones en el modelo de objetos de SharePoint Server alrededor de recorrer en iteración las carpetas en una lista grande.

Jerarquía de la herencia

System.Object
  Microsoft.Office.Server.Utilities.SPFolderHierarchy

Espacio de nombres:  Microsoft.Office.Server.Utilities
Ensamblado:  Microsoft.Office.Server (en Microsoft.Office.Server.dll)

Sintaxis

'Declaración
Public NotInheritable Class SPFolderHierarchy
'Uso
Dim instance As SPFolderHierarchy
public sealed class SPFolderHierarchy

Comentarios

Carpeta de raíz de la lista (SPList.RootFolder) no está contenido en esta colección.Esta abstracción, negocia la memoria para que pueda evitar las consultas costosas necesarias para explorar la jerarquía de carpetas de una lista utilizando la API SPFolder.SubFolders. Esta clase expone las carpetas de la lista como una jerarquía (en comparación con una plana desordenada enumeración de carpetas), lo que sería más eficaz en términos de E/S de SQL y el consumo de memoria de front-end web, pero no habría permitido obtener elementos primarios y secundarios y el orden que coincide con los patrones de acceso convencionales. La clase SPFolderHierarchy intenta recuperar los elementos de la lista de carpetas a través de una consulta (< cref="T:Microsoft.SharePoint.SPQuery"/ Ver >) que tendrá éxito si:

  1. La lista no es grande. Consulte MaxItemsPerThrottledOperation.

  2. El campo de tipo de contenido de la lista se indiza. Consulte ListHasIndexedContentType(SPList).

  3. Hay menos de carpetas de SPWebApplication.MaxItemsPerThrottledOperation en la lista (incluidos los conjuntos de documentos y cualquier otra carpeta de tipo derivado de contenido)

Si ninguna de estas condiciones se cumplen, se reducirá la consulta para los elementos de la carpeta. En ese caso, el SPFolderHierarchy retrocede y trata de obtener el nivel superior de carpetas (es decir, secundarios directos de la lista.RootFolder) mediante el uso de la SPFolder.SubFolders API y a continuación, cada vez que el método SPFolderHierarchy.GetSubFolders(System.String) o se llama al método SPFolderHierarchy.GetSubFolders(System.String,System.Boolean), se realiza otra llamada a la API SPFolder.SubFolders . La consulta en esta llamada está limitada en cuanto una carpeta que contiene más elementos que la propiedad SPWebApplication.MaxItemsPerThrottledOperation se establece para permitir ya sea por el recuento de sucesiones directa o se basa en todo el subárbol, dependiendo de si se han solicitado subcarpetas de recursiva. Solicitar recursiva subcarpetas hará que estas consultas fail mucho antes como una lista crece más allá de establecer el umbral de lista grande. Una vez que el retroceso a comunicación también se reduce la lógica sin solicitar subcarpetas recursiva descritas anteriormente, no hay ninguna manera de obtener la jerarquía de carpetas de la lista sin recorrer en iteración todos los elementos de la lista y tirando de las carpetas. No se recomienda ya que es muy costoso recorrer en iteración todos los elementos de una lista grande.

En su lugar, considere cualquiera:

  1. Índice del campo de tipo de contenido de la lista. Para obtener más información, vea el método EnsureContentTypeIndexedIfLargeList(SPList) , que permitirá el objeto SPFolderHierarchy para utilizar con éxito las consultas get la jerarquía de carpetas de manera eficiente.

  2. Crear una regla de contenido multimedia de la lista para carpeta automático basado en el recuento. Si establece la cuenta automática de carpetas para que los elementos de la carpeta raíz además de recuento de subcarpeta seguirá siendo menor que el recuento de SPWebApplication.MaxItemsPerThrottledOperation hasta que la lista tiene varios millones elementos, debe ser capaz de adaptarse a los casos donde no es posible ordenar el campo de tipo de contenido. Por ejemplo, si SPWebApplication.MaxItemsPerThrottledOperation es 5000 y el número de carpetas de auto se establece en 2000, entonces SharePoint Server puede llegar a aproximadamente 6002000 antes de que se reduce el límite de SPFolder.SubFolders (elementos de2000 más 3000 subcarpetas en la carpeta raíz de la lista). SharePoint Server puede admitir las listas que son más grandes. Si la lista se espera crecer más allá de dos millones de elementos, una planificación más será necesaria.

Ejemplos

using System;

using Microsoft.SharePoint;
using Microsoft.Office.Server.Utilities;
using System.Collections.Generic;
using System.Globalization;

namespace Microsoft.SDK.SharePointServer.Samples
{
    public static class FolderHierarchyCodeSample1
    {
        private static void ProcessFolder(SPFolder folder)
        {
            // Put your code here
        }

        private static void HandleThrottledException(SPException ex)
        {
            // This means the folder hierarchy could not be retrieved.  This happens if all of the following are true:
            // 1. the list does not have an index on the content type ID field (see ContentIterator.ListHasIndexedContentType(SPList))
            // 2. the list was large enough that the folder items could not be queried directly
            // 3. at least one folder in the hierarchy had enough subfolders that SPFolder.SubFolders was also throttled
            //
            // If this happens, there is no way get the folder hierarchy and the SPBuiltInFieldId.ContentTypeId field must
            // be indexed.
        }

        private static void ProcessFolderRecursively(SPFolderHierarchy folders, SPFolder folder)
        {
            ProcessFolder(folder);

            SPFolderHierarchy subFolders = folders.GetSubFolders(folder.ServerRelativeUrl);
            foreach (SPFolder subfolder in ((IEnumerable<SPFolder>)subFolders))
            {
                ProcessFolderRecursively(folders, subfolder);
            }
        }

        public static void ProcessAllFoldersInList(SPList list)
        {
            string viewFields = ContentIterator.FolderCoreViewFields +
                "<FieldRef Name=\"ItemChildCount\"/>" +
                "<FieldRef Name=\"FolderChildCount\"/>";

            // Handle the root web separately since it is not contained in the hierarchy
            ProcessFolder(list.RootFolder);

            // Check if the list has folders other than the root folder
            if (!SPFolderHierarchy.ListHasFolders(list))
                return;

            try
            {
                SPFolderHierarchy folders = new SPFolderHierarchy(list, true, viewFields, true);

                Console.WriteLine(string.Format(CultureInfo.InvariantCulture, 
                    "Total # of folders in list:  {0}",
                    folders.Count));

                SPFolderHierarchy subFolders = folders.GetSubFolders(list.RootFolder.ServerRelativeUrl);
                foreach (SPFolder subfolder in ((IEnumerable<SPFolder>)subFolders))
                {
                    ProcessFolderRecursively(folders, subfolder);
                }
            }
            catch (SPQueryThrottledException ex)
            {
                HandleThrottledException(ex);
            }
        }
    }
}

using System;

using Microsoft.SharePoint;
using Microsoft.Office.Server.Utilities;
using System.IO;

namespace Microsoft.SDK.SharePointServer.Samples
{
    class FolderHierarchyCodeSample2
    {
        // Replace with your folder name
        private static string templateFolder = "AdventureWorksTemplates";

        private static void ProcessFolder(SPFolder folder)
        {
            // Put your code here
        }

        public static void ProcessFoldersFromList(SPList list, string[] folderUrls)
        {
            // Create a folder hierarchy instead of making one query per folder
            SPFolderHierarchy folders = new SPFolderHierarchy(list, true);

            foreach (string folderUrl in folderUrls)
            {
                SPFolder folder;

                if (folders.TryGetFolder(folderUrl, out folder))
                {
                    if (folder.Exists)
                    {
                        ProcessFolder(folder);
                    }
                }
            }
        }

        public static void ProcessFoldersFromWeb(SPWeb web, string[] folderUrls)
        {
            // Since folderUrls may span many lists, do not create folder hierarchies
            foreach (string folderUrl in folderUrls)
            {
                SPFolder folder;

                // Try to get the folder and make sure it exists (this does not create the folder if it does not)
                if (SPFolderHierarchy.TryGetFolderByUrl(web, folderUrl, true, out folder))
                {
                    ProcessFolder(folder);
                }
            }
        }

        public static SPFile AddTemplateResource(SPSite site, Stream fileStream, string fileName)
        {
            // Get (and create if it does not exist) a folder off of site.RootWeb.RootFolder to use to store resource files
            SPFolder resourceFolder = SPFolderHierarchy.GetSiteCollectionResourceFolder(site, templateFolder, true);

            // Create the file or update it if it already exists
            return resourceFolder.Files.Add(fileName, fileStream, true);
        }
    }
}

Seguridad para subprocesos

Los miembros static (Shared en Visual Basic) públicos de este tipo son seguros para subprocesos. No se garantiza que los miembros de instancias sean seguros para los subprocesos.

Vea también

Referencia

Miembros SPFolderHierarchy

Espacio de nombres Microsoft.Office.Server.Utilities