Share via


SPFolderHierarchy-Klasse

Diese Klasse ist eine Abstraktion für die Ordner in einer SharePoint Server Liste umgehen Einschränkungen im SharePoint Server -Objektmodell, um die Ordner in einer umfangreichen Liste durchlaufen soll.

Vererbungshierarchie

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

Namespace:  Microsoft.Office.Server.Utilities
Assembly:  Microsoft.Office.Server (in Microsoft.Office.Server.dll)

Syntax

'Declaration
Public NotInheritable Class SPFolderHierarchy
'Usage
Dim instance As SPFolderHierarchy
public sealed class SPFolderHierarchy

Hinweise

Stammordner für die Liste (SPList.RootFolder) ist nicht Inhalt dieses Auflistung enthalten.Diese Abstraktion ein Kompromiss zwischen Speicher erforderlichen, um eine Liste Ordner-Hierarchie mithilfe der SPFolder.SubFolders-API navigieren teuren Abfragen zu vermeiden können. Diese Klasse stellt die in der Liste Ordner entspricht eine Hierarchie (im Vergleich zu einer flachen ungeordnete Aufzählung von Ordnern), wäre die effizienteste in Bezug auf e/a-SQL und Web-front-End-Speicherverbrauch, aber hätte nicht zugelassen, hierarchische und Sortierreihenfolge zu erhalten, die herkömmliche Zugriffsmuster. Die SPFolderHierarchy-Klasse versucht, die Ordnerlistenelemente über eine Abfrage abrufen (< finden Sie unter cref="T:Microsoft.SharePoint.SPQuery"/ >) die erfolgreich, wenn:

  1. Die Liste ist nicht groß. Finden Sie unter MaxItemsPerThrottledOperation.

  2. Das Content-Type-Feld in der Liste wird indiziert. Finden Sie unter ListHasIndexedContentType(SPList).

  3. Es gibt weniger als SPWebApplication.MaxItemsPerThrottledOperation-Ordner in der Liste (einschließlich Dokumentenmappen und alle anderen Ordner abgeleiteten Inhaltstyp)

Wenn keine dieser Bedingungen zutrifft, wird die Abfrage für die Ordnerelemente gedrosselt. In diesem Fall die SPFolderHierarchy fällt zurück und versucht die oberste Ebene der Ordner (d. h. direkt untergeordnete Liste.RootFolder) mithilfe der SPFolder.SubFolders -API und anschließend wird jede Zeit die SPFolderHierarchy.GetSubFolders(System.String) -Methode oder die SPFolderHierarchy.GetSubFolders(System.String,System.Boolean)-Methode aufgerufen wird, rufen Sie die API SPFolder.SubFolders erfolgt. Die Abfrage in diesem Aufruf gedrosselt wird, sobald ein Ordner, der mehr Elemente als die SPWebApplication.MaxItemsPerThrottledOperation -Eigenschaft enthält, wird entweder durch direkte Nachfolger zählen zu können oder basierend auf die gesamte Teilstruktur, je nachdem, ob Unterordner rekursiv angefordert wurden. Anfordern, Unterordner rekursive Abfragen werden wächst Fail eher eine Liste über die umfangreiche Liste immer dann. Sobald die Klartextkommunikation ohne Anforderung einer rekursiven Unterordner oben beschriebene Logik auch gedrosselt, gibt es keine Möglichkeit, die Ordnerhierarchie der Liste ohne Durchlaufen aller Elemente in der Liste, und ziehen Sie die Ordner abzurufen. Dies wird nicht empfohlen, da es sehr teuer, alle Elemente in einer umfangreichen Liste durchlaufen wird.

Stattdessen sollten Sie entweder:

  1. Die Indizierung des Content-Type-Felds in der Liste. Weitere Informationen finden Sie unter der EnsureContentTypeIndexedIfLargeList(SPList) -Methode, die dem SPFolderHierarchy -Objekt erfolgreich Abfragen Get verwenden die Ordnerhierarchie auf effiziente Weise ermöglichen.

  2. Erstellen Sie eine Regel Inhaltsorganisation für die Liste basierend auf der Anzahl der Auto-Ordner. Wenn Sie die Anzahl der Auto-Ordner festlegen, damit die Root-Ordnerelemente und Unterordner Count kleiner als die Anzahl der SPWebApplication.MaxItemsPerThrottledOperation bleiben , bis die Liste mehrere Millionen Elemente hat, sollten Sie möglicherweise für den Fall, in dem nicht das Content-Type-Feld indiziert werden kann. Z. B. wenn SPWebApplication.MaxItemsPerThrottledOperation5000 und die Anzahl der Ordner automatisch auf 2000festgelegt ist, dann SharePoint Server erhalten, etwa die 6002000 vor der Drosselung auf SPFolder.SubFolders gedrosselt wird (2000 Elemente und Unterordner im Stammordner der Liste der 3000 ). SharePoint Server können Listen unterstützt, die größer sind. Wenn die Liste über zwei Millionen Elemente wachsen erwartet wird, werden mehr Planung benötigt.

Beispiele

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

Threadsicherheit

Alle öffentlichen static (Shared in Visual Basic) Member dieses Typs sind threadsicher. Die Threadsicherheit von Instanzmembern ist nicht gewährleistet.

Siehe auch

Referenz

SPFolderHierarchy-Member

Microsoft.Office.Server.Utilities-Namespace