SharePoint получает имя ContentType

Я пытаюсь получить все папки и файлы из библиотеки SharePoint, выполняя один запрос.

CamlQuery query = new CamlQuery();
query.ViewXml = "<View Scope='RecursiveAll' />";
var libraryName = "Specific Documents";

ListItemCollection itemsRaw = clientContext.Web.Lists.GetByTitle(libraryName).GetItems(query);
clientContext.Load(itemsRaw);
clientContext.ExecuteQuery();

Этот код работает хорошо, и в результате у меня есть список всех папок и файлов в указанной библиотеке.

Кажется, что детали файлов загружаются лениво. Только первый уровень иерархии деталей. Но я не знаю как, коллекция FieldValues заполнена данными.

Сведения об элементе списка

Я вижу, что ListItem ContentType.Name не инициализирован.

Имя ContentType не инициализировано

Можно ли как-то обновить запрос таким образом, чтобы загружать данные для ContentType в этом единственном вызове.

Или единственная возможность - перебрать все файлы и выполнить загрузку ContentType для конкретного файла?

Я сделал это следующим образом:

foreach(var listItem in listItemCollection)
{
    context.Load(listItem, k => k.ContentType);
    context.ExecuteQuery();
    var contentTypeName = listItem.ContentType.Name;
}

Но я собираюсь получить эту информацию за один вызов, если это возможно, без итерации в коллекции и запуска нескольких вызовов ClientContext.

P.S.: я новичок в программировании SharePoint. Я просто хочу исправить ошибку.

Спасибо!


person mihai    schedule 13.02.2015    source источник


Ответы (2)


Как вы правильно заметили в клиентской объектной модели SharePoint (CSOM) Метод ClientRuntimeContext.Load не извлекает все свойства для объекта клиента.

ClientRuntimeContext.Load Method имеет следующий синтаксис. :

public void Load<T>(
    T clientObject,
    params Expression<Func<T, Object>>[] retrievals
)
where T : ClientObject        

где параметр retrievals предназначен для указания свойств, которые необходимо получить.

Во-вторых, поскольку CSOM SharePoint поддерживает пакетную обработку запросов, ваш пример можно изменить на Вот этот:

foreach (var item in items)
{
    ctx.Load(item, i => i.ContentType);
}
ctx.ExecuteQuery();

Примечание: в этом примере запрос отправляется на сервер только один раз.

Но все же приведенный пример требует двух запросов к серверу:

  • получить элементы списка
  • получить тип содержимого для элементов списка

и его можно улучшить с точки зрения производительности, уменьшив количество запросов к серверу до одного.

Последний пример

В примере показано, как получить элементы списка и явно указать, какие свойства нужно получить:

 var listTitle = "Documents";
 var query = new CamlQuery();
 query.ViewXml = "<View Scope='RecursiveAll' />";

 var items = ctx.Web.Lists.GetByTitle(listTitle).GetItems(query);
 ctx.Load(items,icol => icol.Include(
                i => i.ContentType,
                i => i.FieldValues));
 ctx.ExecuteQuery();
person Vadim Gremyachev    schedule 13.02.2015
comment
Спасибо Вадим, за ответ! - person mihai; 15.02.2015
comment
Я просто попытался использовать последний пример. Я получил ошибку: Выражение запроса не поддерживается. Есть ли способ заставить его работать? - person mihai; 16.02.2015
comment
Когда я редактирую выражение ctx.Load(items, icol => icol.Include (i => i.ContentType));, оно выполняется нормально. Но мне тоже нужны FieldValues. :) Я что-то упускаю в ctx.Load(items, icol => icol.Include (i => i.ContentType, i => i.FieldValues)); и в результате получаю эту ошибку? - person mihai; 16.02.2015

Последний пример не работает (в SP2010).

Существует исключение «Выражение запроса не поддерживается». Если вы явно указываете все обязательные поля, то решение ниже работает.

var listTitle = "Documents";
var query = new CamlQuery();
query.ViewXml = "<View Scope='RecursiveAll' />";

var items = ctx.Web.Lists.GetByTitle(listTitle).GetItems(query);

string[] fieldsToMigrate = new string[] { "Title", "FieldA", "FieldB" };
ctx.Load(items, a => a.Include(b => b.ContentType, b => b["FileRef"]));
foreach (var f in fieldsToLoad) {
    ctx.Load(items, includes => includes.Include(a => a[f]));
}

ctx.ExecuteQuery();
person Martin P.    schedule 03.05.2016