SharePoint CSOM: заредете свойството FileSystemObjectType от GetChanges()

Използвам Web.GetChanges(), за да извлека редица промени от уеб на SharePoint.

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

Не мога да намеря начин да заредя това свойство:

Не мога да го заредя, когато извикам GetChanges(), защото FileSystemObjectType е свойство на ChangeItem, а не на Change (върнато от GetChanges);

Не мога да го използвам, след като прехвърлям Change to 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
Благодаря ти Vladim, вариант две е интересен подход. И двете опции изискват две извиквания към ExecuteQuery (което се надявах да избегна), така че мисля, че по отношение на производителността са равни? Докато съм тук, знаете ли дали има някакъв начин да извлечете промени само за избрани списъци, но все пак с едно извикване? - person Francesco; 10.09.2018