14

私がこれを行う場合:

_calendar = (CalendarFolder)Folder.Bind(_service, WellKnownFolderName.Calendar);

var findResults = _calendar.FindAppointments(
    new CalendarView(startDate.Date, endDate.Date)
);

見つかったアイテムが多すぎるという例外が発生することがあります。

「検索操作で返すことができるオブジェクトの最大数を超えました。ページングを使用して結果のサイズを減らし、要求を再試行してください。」

CalendarViewを指定できるコンストラクタをサポートしていますが、ページング用MaxItemsReturnedに を指定して再度呼び出す方法がわかりません。このコンストラクタがあります:offsetItemView

 public ItemView(int pageSize, int offset)

そして、その使用法は明らかです。

どうCalendarViewですか?でページングを行うにはどうすればよいCalendarViewですか?

日付範囲を短くすることはできますが、確実に機能するかどうかを判断する方法はまだありません。

4

3 に答える 3

8

CalendarViewは実際にはPagedViewから派生したものではないため、期待されるすべてのページング ロジックは実現できません。MaxItemsReturned は、ページ サイズよりも上限です。返されるエラーは、PagedView 派生ビュー タイプに関連しています。

最後に返されたアイテムに基づいて CalendarView ウィンドウをローリングすることでページングをエミュレートするために、いくつかの PowerShell をいじりましたが、残念ながら、CalendarView と Appointment 拡張の背後にあるロジックにより、必要なものを正確に取得することは不可能です。基本的に、拡張を行うと、「N」個のアイテムで停止しますが、まったく同時に開始する複数の予定があり、1 つが表示されても、残りが表示されない場合があります。また、ウィンドウに重なる予定も含まれるため、カレンダーに 50 件の予定があり、すべてが同じ開始時刻である場合、以下のコードは無限ループに陥ります。

Add-Type -Path "C:\Program Files\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll"

$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService
$cred = New-Object Microsoft.Exchange.WebServices.Data.WebCredentials ($user , $passwd)
$service.UseDefaultCredentials = $false
$service.Credentials = $cred
$service.AutodiscoverUrl($user)

$num=50
$total=0
$propsetfc = [Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties
$calfolder = [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar

$service.UserAgent = "EWSCalViewTest"
$calview = New-Object Microsoft.Exchange.WebServices.Data.CalendarView("1/1/2012","12/31/2012", $num)
$calview.PropertySet = $propsetfc

do {
    $findresults = $service.FindAppointments($calfolder,$calview)
    write-host  "Found:" $findresults.Items.Count "of" $findresults.TotalCount
    $calview.StartDate = $findresults.Items[$findresults.Items.Count-1].Start
    $total+=$findresults.Items.Count
} while($findresults.MoreAvailable)
write-host $total "total found (including dups)"

残念ながら、拡張とオーバーラップのロジックは、この方法で重複を取得することを意味します。最初の呼び出しを超えて、各呼び出しに対して少なくとも 1 つの重複があります。

CalendarView を使用してコードを記述しなければならない場合、おそらく 1000 の MaxItemsReturned を使用するでしょう (これは、MaxItemsReturned を指定しない場合にエラー状態に陥る制限でもあります)。1回の通話でそれらすべてを取得できれば、問題ありません。2 回目の呼び出しを行う必要がある場合は、結果セットを重複除去するために追加の作業を行う必要があります。また、Exchange に全期間にわたる定期的な予定の拡張を計算するように要求しているため、CalendarView で可能な限り狭い日付ウィンドウを使用して、サーバーの負担を制限しようとします。これは、サーバーにとってかなりコストのかかる操作になる可能性があります。

于 2012-08-19T19:21:59.460 に答える
1

ItemViewと を使用して、SearchFilter予定を照会できます。

var itemView = new ItemView(100, 0);
itemView.PropertySet = new PropertySet(BasePropertySet.IdOnly,
    ItemSchema.Subject, AppointmentSchema.Start, AppointmentSchema.End);

var filter = new SearchFilter.SearchFilterCollection(LogicalOperator.And,
    new SearchFilter.IsEqualTo(ItemSchema.ItemClass, "IPM.Appointment"),
    new SearchFilter.IsGreaterThanOrEqualTo(AppointmentSchema.Start, startDate),
    new SearchFilter.IsLessThan(AppointmentSchema.Start, endDate));

bool moreAvailable = true;
while (moreAvailable)
{
    var result = _service.FindItems(WellKnownFolderName.Calendar, filter, itemView);

    foreach (var appointment in result.OfType<Appointment>())
    {
        DateTime start = appointment.Start;
        DateTime end = appointment.End;
        string subject = appointment.Subject;

        // ...
    }

    itemView.Offset += itemView.PageSize;
    moreAvailable = result.MoreAvailable;
}
于 2014-01-28T19:21:47.907 に答える