SPFolderHierarchy 类

此类通过旨在解决周围循环大列表中的文件夹的SharePoint Server对象模型中的限制SharePoint Server列表中的文件夹是一种抽象。

继承层次结构

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

命名空间:  Microsoft.Office.Server.Utilities
程序集:  Microsoft.Office.Server(位于 Microsoft.Office.Server.dll 中)

语法

声明
Public NotInheritable Class SPFolderHierarchy
用法
Dim instance As SPFolderHierarchy
public sealed class SPFolderHierarchy

备注

此列表中的根文件夹 (SPList.RootFolder) 不是包含此集合。这种抽象形式权衡能够避免昂贵的查询浏览列表的文件夹层次结构使用 SPFolder.SubFolders API 所需的内存。此类公开此列表中的文件夹 (而不是平面无序的枚举文件夹),这将是最有效的 SQL IO 和 web 前端内存消耗,但将不允许获取父-子和排序顺序的层次结构匹配常规访问模式。SPFolderHierarchy 类尝试检索通过查询文件夹列表项 (< 见 cref="T:Microsoft.SharePoint.SPQuery"/ >) 这会成功如果:

  1. 该列表不是大的。请参阅MaxItemsPerThrottledOperation

  2. 在列表中的内容类型字段编制索引。请参阅ListHasIndexedContentType(SPList)

  3. 有超过 SPWebApplication.MaxItemsPerThrottledOperation (包括文档集和任何其他文件夹派生内容类型) 的列表中的文件夹数

如果这些条件都满足,文件夹项目的查询将被控制。在这种情况下, SPFolderHierarchy将回退并尝试获取的顶层文件夹 (例如,列表的直接子级。RootFolder) 通过使用SPFolder.SubFolders API,然后每次SPFolderHierarchy.GetSubFolders(System.String)方法或调用 SPFolderHierarchy.GetSubFolders(System.String,System.Boolean) 方法时,另一个调用到SPFolder.SubFolders API。一旦包含更多的项目,比的SPWebApplication.MaxItemsPerThrottledOperation属性的文件夹被设置为允许通过盘点直接 decendents 或基于根据递归子文件夹是否已请求的整个子树,则此调用中的查询被遏制。请求递归子文件夹会使这些查询失败更快以列表的形式增长到超过大型列表阈值。一旦后退而不请求上面所述的递归子文件夹的逻辑也被遏制,就没有办法获得列表中的文件夹层次结构,而不必遍历列表中的每个项并拉出文件夹。这不是推荐的因为它是非常昂贵的方法来循环访问大列表中的所有项目。

相反,请考虑任何一个:

  1. 索引列表上的内容类型字段。若要了解详细信息,请参阅EnsureContentTypeIndexedIfLargeList(SPList)方法中,以高效的方式将允许SPFolderHierarchy对象成功地使用查询获取文件夹层次结构。

  2. 创建列表的内容,根据计数自动文件夹的内容管理器规则。如果您将设置为自动文件夹计数的根文件夹项目加上子文件夹计数之前将一直保持小于SPWebApplication.MaxItemsPerThrottledOperation数的列表有多个万个项目,应该能够容纳在其中不能索引内容类型字段的情况。例如,如果SPWebApplication.MaxItemsPerThrottledOperation是5000 ,并且自动文件夹计数会设置为2000,然后SharePoint Server之前,可获得大约6002000到限制在SPFolder.SubFolders上被遏制 (2000项目加上3000中的列表中的根文件夹的子文件夹)。SharePoint Server可以支持更大的列表。如果列表预计增长超过两百万的项目,更多的规划将是必需的。

示例

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

线程安全性

该类型的任何公共 静态 (已共享 在 Visual Basic 中) 成员都是线程安全的。不保证任何实例成员都是线程安全的。

另请参阅

引用

SPFolderHierarchy 成员

Microsoft.Office.Server.Utilities 命名空间