SharePoint CSOM: загрузка свойства FileSystemObjectType из GetChanges()

Я использую Web.GetChanges() для получения ряда изменений из сети SharePoint.

Мне нужно просмотреть изменения и для каждого изменения, которое является ChangeItem, проверить свойство FileSystemObjectType (чтобы различать изменения элементов и изменения папок).

Я не могу найти способ загрузить это свойство:

Я не могу загрузить его, когда вызываю GetChanges(), потому что FileSystemObjectType является свойством ChangeItem, а не Change (возвращается из GetChanges);

Я не могу использовать его после того, как применил Change к ChangeItem, потому что он возвращает исключение «Свойство не инициализировано».

Это фрагмент кода, о котором идет речь:

ChangeCollection changes = spcn.RootWeb.NativeWeb.GetChanges(query);

/* I cannot include FileSystemObjectType here */
spcn.RootWeb.NativeWeb.Context.Load(changes); //, c => c.Include(o => o.FileSystemObjectType));
spcn.RootWeb.NativeWeb.Context.ExecuteQuery();

foreach (Change change in changes)
{
    Console.Write($"{change.GetType().Name} {change.ChangeType} {change.Time} "); 

    if (change is ChangeItem)
    {
        ChangeItem ci = (ChangeItem)change;

        /* FileSystemObjectType is *not* initalised here */ 
        Console.WriteLine($"{ci.ItemId} {ci.FileSystemObjectType}");
    }

Я надеюсь, что это достаточно ясно, дайте мне знать, если это не так (NativeWeb — это SharePoint Web).

Любые идеи, как я могу загрузить это свойство?

Спасибо.


person Francesco    schedule 30.08.2018    source источник


Ответы (1)


Здесь можно рассмотреть как минимум два варианта:

Вариант 1

явно указать загружать только ChangeItem через Microsoft.SharePoint.Client.ChangeQuery:

var changeQuery = new ChangeQuery(false,true);
changeQuery.Item = true; //only load change item changes

а затем запросить загрузку определенных свойств ChangeItem следующим образом:

  ctx.Load(changes, cc => cc.Include(c => ((ChangeItem)c).FileSystemObjectType));

Пример

var changeQuery = new ChangeQuery(false,true);
changeQuery.Item = true; //only load change item changes
var changes = ctx.Web.GetChanges(changeQuery);
ctx.Load(changes, cc => cc.Include(c => c.ChangeType, c => ((ChangeItem)c).FileSystemObjectType));
ctx.ExecuteQuery();

foreach(var change in changes)
{
     ChangeItem changeItem = change as ChangeItem;
     Console.WriteLine("{0}: {1}",changeItem.ChangeType,changeItem.FileSystemObjectType);
}

Вариант 2

Допустим, вы загружаете все изменения заранее, например так:

var changeQuery = new ChangeQuery(true,true);
var changes = ctx.Web.GetChanges(changeQuery);
ctx.Load(changes);
ctx.ExecuteQuery();

Затем можно запросить определенные свойства объекта ChangeItem с помощью дополнительного запроса, например:

var changeItems = changes.OfType<ChangeItem>();
var changeItemsResult = ctx.LoadQuery(changeItems.Include(c =>c.ChangeType, c => c.FileSystemObjectType));
ctx.ExecuteQuery();

foreach (var changeItem in changeItemsResult)
{
     Console.WriteLine("{0}: {1}",changeItem.ChangeType,changeItem.FileSystemObjectType);
}
person Vadim Gremyachev    schedule 03.09.2018
comment
Спасибо Влад, второй вариант интересный подход. Оба варианта требуют двух вызовов ExecuteQuery (это то, чего я надеялся избежать), поэтому я думаю, что с точки зрения производительности они равны? Пока я здесь, не знаете ли вы, есть ли способ получить изменения только для выбранных списков, но все же одним вызовом? - person Francesco; 10.09.2018