Partager via


SPFolderHierarchy - Classe

Cette classe est une abstraction sur les dossiers dans une liste de SharePoint Server conçu pour contourner les limitations du modèle d'objet SharePoint Server autour d'itérer les dossiers dans une grande liste.

Hiérarchie d’héritage

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

Espace de noms :  Microsoft.Office.Server.Utilities
Assembly :  Microsoft.Office.Server (dans Microsoft.Office.Server.dll)

Syntaxe

'Déclaration
Public NotInheritable Class SPFolderHierarchy
'Utilisation
Dim instance As SPFolderHierarchy
public sealed class SPFolderHierarchy

Remarques

Dossier racine de la liste (SPList.RootFolder) n'est pas contenu contenu de cette collection.Cette abstraction de transactions hors mémoire pour éviter les requêtes coûteuses pour naviguer dans la hiérarchie de dossiers d'une liste à l'aide de l'API SPFolder.SubFolders. Cette classe expose les dossiers de la liste comme une hiérarchie (par opposition à une plat non ordonné l'énumération des dossiers), ce qui serait la plus efficace en termes d'e/s de SQL et de la consommation de mémoire web front-end, mais n'eut pas permis l'obtention de parent-enfant et ordre de tri qui correspond à des modèles d'accès classiques. La classe SPFolderHierarchy tente d'extraire les éléments de liste de dossier via une requête (< voir cref="T:Microsoft.SharePoint.SPQuery"/ >) qui réussira si :

  1. La liste n'est pas importante. Voir MaxItemsPerThrottledOperation.

  2. Le champ de type de contenu de la liste est indexé. Voir ListHasIndexedContentType(SPList).

  3. Il y a moins de dossiers SPWebApplication.MaxItemsPerThrottledOperation dans la liste (y compris les ensembles de documents et tout autre dossier content type dérivé)

Si aucune de ces conditions sont remplies, la requête pour les éléments du dossier est accélérée. Dans ce cas, le SPFolderHierarchy se replie et essaie d'obtenir le niveau supérieur des dossiers (c'est-à-dire, les enfants directs de la liste.RootFolder) à l'aide de la SPFolder.SubFolders API, puis chaque fois que la méthode SPFolderHierarchy.GetSubFolders(System.String) ou la méthode SPFolderHierarchy.GetSubFolders(System.String,System.Boolean) est appelée, un autre appel à l'API SPFolder.SubFolders est effectué. La requête de cet appel est limitée dès qu'un dossier qui contient plus d'éléments que la propriété SPWebApplication.MaxItemsPerThrottledOperation est défini pour permettre soit en comptant les descendants directs ou basé sur l'ensemble du sous-arbre en fonction de si les sous-dossiers récursives ont été demandées. Demande récursive les sous-dossiers rendra ces requêtes échouent beaucoup plus tôt en tant que liste s'élargit au-delà de la demi-teinte grande liste. Une fois l'automne précédent logique sans demander de sous-dossiers récursive décrites ci-dessus est limitée également, il n'existe aucun moyen d'obtenir la hiérarchie de dossiers de la liste sans itérer sur chaque élément de la liste et en tirant les dossiers. Ce n'est pas recommandé car elle est très coûteuse itérer sur tous les éléments d'une grande liste.

Songez plutôt à une ou l'autre :

  1. L'indexation du champ de type de contenu de la liste. Pour en savoir plus, consultez la méthode EnsureContentTypeIndexedIfLargeList(SPList) , qui permettra à l'objet SPFolderHierarchy à utiliser avec succès les requêtes get la hiérarchie des dossiers de manière efficace.

  2. Créer une règle d'organisateur de contenu pour la liste automatique basé sur le nombre de dossier. Si vous définissez le nombre de dossiers d'automatique afin que les éléments du dossier racine ainsi que nombre de sous-dossier reste inférieur au nombre de SPWebApplication.MaxItemsPerThrottledOperation jusqu'à ce que la liste comporte plusieurs éléments de millions, vous devez être en mesure de prendre en charge les cas où il n'est pas possible d'indexer le champ de type de contenu. Par exemple, si SPWebApplication.MaxItemsPerThrottledOperation est 5000 et le nombre de dossiers d'automatique est défini sur 2000, puis SharePoint Server peut atteindre environ 6002000 avant la limitation de la SPFolder.SubFolders est limitée (éléments2000 plus 3000 les sous-dossiers dans le dossier racine de la liste). SharePoint Server peut prendre en charge des listes qui sont plus grands. Si la liste est censée croître au-delà de deux millions d'éléments, la planification plus soigneuse sera nécessaire.

Exemples

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);
        }
    }
}

Cohérence de thread

Tous les membres statique (Partagé dans Visual Basic)s publics de ce type sont thread-safe. Cela n’est pas garanti pour les membres d’instance.

Voir aussi

Référence

SPFolderHierarchy - Membres

Microsoft.Office.Server.Utilities - Espace de noms