SharePoint.Client Рекурсивно получить все папки

Я хотел бы вызвать clientContext.ExecuteQuery() один раз для повышения производительности сайта.

Коллекции вещей, которые я хочу загрузить, включают все папки и файлы для всех библиотек документов на сайте. Когда я говорю ВСЕ, я действительно имею в виду ВСЕ. т. е. если есть папки внутри папок, внутри папок, я хочу их все за один раз. Возможно ли это, или мне нужно придерживаться рекурсивной загрузки каждой дочерней папки и явной загрузки ее папок и файлов.

То, что у меня есть прямо сейчас, получает папки базового уровня и рекурсивно получает остальные:

private static void SharePoint()
{
    var clientContext = new ClientContext(@"http://myURL")
                            {
                                Credentials = System.Net.CredentialCache.DefaultCredentials
                            };


    var web = clientContext.Web;
    clientContext.Load(web);
    clientContext.Load(web.Folders);
    clientContext.Load(web.Lists, lists => lists.Include(l => l.ContentTypes.Include(c => c.Fields),
                                                              l => l.BaseType,
                                                              l => l.Hidden,
                                                              l => l.RootFolder,
                                                              l => l.RootFolder.Files.Include(fi => fi.ListItemAllFields, 
                                                                                              fi => fi.ListItemAllFields.ContentType,
                                                                                              fi => fi.Name),
                                                              l => l.RootFolder.Folders,
                                                              l => l.Title));
    clientContext.ExecuteQuery();

    var documentLibraries = web.Lists.ToList().Where(l => l.BaseType == BaseType.DocumentLibrary && !l.Hidden).ToList();
    foreach (var folder in documentLibraries.SelectMany(documentLibrary => documentLibrary.RootFolder.Folders.ToList().Where(fo => fo.Name != "Forms")))
    {
        LoadFolders(clientContext, folder);
    }
}

private static void LoadFolders(ClientContext clientContext, Folder folder)
{
    clientContext.Load(folder.Files, files => files.Include(fi => fi.ListItemAllFields,
                                                                fi => fi.ListItemAllFields.ContentType,
                                                                fi => fi.Name)); 
    clientContext.Load(folder.Folders);
    clientContext.ExecuteQuery();
    foreach (var childFolder in folder.Folders)
    {
        LoadFolders(clientContext, childFolder);
    }
}

person The K2 Guy    schedule 20.05.2013    source источник
comment
Запрос CAML может быть подходящим способом — вам повезло?   -  person johnnycardy    schedule 16.07.2013


Ответы (1)


Поскольку CSOM SharePoint поддерживает пакетную обработку запросов, вы можете рассмотреть следующий подход для получения содержимое (файлы и папки):

    public static void LoadContent(Web web, out Dictionary<string, IEnumerable<Folder>> listsFolders, out Dictionary<string, IEnumerable<File>> listsFiles)
    {
        listsFolders = new Dictionary<string, IEnumerable<Folder>>();
        listsFiles = new Dictionary<string, IEnumerable<File>>();
        var listsItems = new Dictionary<string, IEnumerable<ListItem>>();

        var ctx = web.Context;
        var lists = ctx.LoadQuery(web.Lists.Where(l => l.BaseType == BaseType.DocumentLibrary));
        ctx.ExecuteQuery();

        foreach (var list in lists)
        {
            var items = list.GetItems(CamlQuery.CreateAllItemsQuery());
            ctx.Load(items, icol => icol.Include(i => i.FileSystemObjectType, i => i.File, i => i.Folder));
            listsItems[list.Title] = items;
        }
        ctx.ExecuteQuery();

        foreach (var listItems in listsItems)
        {
            listsFiles[listItems.Key] = listItems.Value.Where(i => i.FileSystemObjectType == FileSystemObjectType.File).Select(i => i.File);
            listsFolders[listItems.Key] = listItems.Value.Where(i => i.FileSystemObjectType == FileSystemObjectType.Folder).Select(i => i.Folder); 
        }
    }

использование

  using (var ctx = new ClientContext(webUrl))
  { 
      Dictionary<string, IEnumerable<Folder>> listsFolders;
      Dictionary<string, IEnumerable<File>> listsFiles;
      LoadContent(ctx.Web,out listsFolders,out listsFiles);
  }
person Vadim Gremyachev    schedule 14.12.2014
comment
Это сглаживает структуру папок. Есть идеи, как этого избежать? - person Mzn; 22.08.2016
comment
@Mzn, действительно, но объект Folder содержит информацию о пути к папке. Может есть смысл создать отдельный вопрос и я в числе прочих разберусь? - person Vadim Gremyachev; 22.08.2016
comment
Есть ли способ сделать это, чтобы просто вернуть папки и подпапки, но не файлы? Мне нужна только структура папок из корня. - person Stephen McCormick; 06.02.2018