2012-08-17 17 views
11

Gdybym to zrobić:Jak zrobić stronicowania z Exchange Web Services CalendarView

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

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

czasami uzyskać wyjątek, które znajdowały się zbyt wiele elementów.

"Przekroczono maksymalną liczbę obiektów, które można zwrócić w celu znalezienia. Użyj stronicowania, aby zmniejszyć rozmiar wyniku i spróbuj ponownie."

CalendarView obsługuje konstruktora, który pozwoli mi określić MaxItemsReturned, ale nie mogę dowiedzieć się, jak będę go nazwać ponownie, określając offset dla stronicowania. ItemView ma tego konstruktora:

public ItemView(int pageSize, int offset) 

I użycie tego jest oczywiste.

Co z numerem CalendarView? Jak zrobić stronicowanie z CalendarView?

Mogę zmniejszyć zakres dat, aby uzyskać krótszą rozpiętość, ale nadal nie można ustalić, czy zadziała na pewno.

Odpowiedz

8

CalendarView nie jest faktycznie wyprowadzony z PagedView, więc cała oczekiwana logika stronicowania nie jest możliwa. MaxItemsReturned to więcej górnego limitu niż rozmiar strony. Zwrócony błąd jest bardziej odpowiedni dla typów widoku pochodnego PagedView.

Grałem z PowerShell emulować stronicowanie, przewracając okno CalendarView na podstawie ostatniego zwróconego przedmiotu, ale niestety logika rozwoju kalendarza i spotkania nie pozwala uzyskać dokładnie tego, czego potrzebujesz. Zasadniczo, tak jak ekspansja, zatrzyma się na elementach "N", ale możesz mieć więcej niż jedno spotkanie, które rozpoczyna się dokładnie w tym samym czasie i może ci dać jedno, ale nie resztę. Ponadto wszystkie spotkania pokrywające się z oknem zostaną uwzględnione, więc poniższy kod zostanie wprowadzony w nieskończoną pętlę, jeśli masz 50 terminów w kalendarzu, z których wszystkie miały ten sam czas rozpoczęcia.

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)" 

Niestety ekspansja i logika pokrywają oznaczać dostaniesz duplikatów w ten sposób, co najmniej jeden duplikat dla każdego połączenia poza pierwszym.

Gdybym musiał napisać kod używając CalendarView, prawdopodobnie użyłbym MaxItemsReturned z 1000 (jest to również limit, który rzuca cię na warunek błędu, jeśli nie określisz MaxItemsReturned). Jeśli uzyskasz je wszystkie w jednym połączeniu, jesteś dobry. Jeśli musisz wykonać drugie połączenie, musisz wykonać dodatkową pracę, aby odfiltrować zestaw wyników. Próbuję też ograniczyć obciążenie serwera, wykorzystując jako wąskie okno daty w widoku kalendarza, ponieważ pytasz Exchange, aby obliczyć ekspansję powtarzających się spotkań w całym przedziale czasowym. Może to być dość kosztowna operacja dla serwera.

+0

Dobre rzeczy RickH, ale wciąż nie są wystarczająco deterministyczne dla mnie. W międzyczasie zrobiłem przerwę na kilka miesięcy i korzystałem z 'CalendarView' dla każdego miesiąca. Wydaje się działać dobrze. – tig

+0

"Koszt przetwarzania serwera" jest zasadniczo taki sam, niezależnie od tego, czy robię to przez cały rok, czy z 12-miesięcznymi zakresami, czy nie? – tig

+0

Mimo że odpowiedź w rzeczywistości nie rozwiązuje mojego problemu, należy podać odpowiedź: Nie można wykonać stronicowania w stylu PagedmView za pomocą kalendarza. Oznaczając to jako odpowiedź. – tig

0

Można użyć ItemView i SearchFilter kwerendy nominacje:

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; 
} 
+3

To nie rozszerza występowania powtarzających się wzorców, a zatem zapewnia niepełny widok kalendarza, o ile wiem. Właśnie dlatego 'CalendarView' jest tak przydatny (z wyjątkiem faktu, że nie jest dobrze na stronie) – jessehouwing

0

Nadal można paginate funkcję FindAppointments manipulując CalendarView daty rozpoczęcia.

var cal = CalendarFolder.Bind(_service, WellKnownFolderName.Calendar); 
var cv = new CalendarView(start, end, 1000); 

var appointments = new List<Appointment>(); 

var result = cal.FindAppointments(cv); 

appointments.AddRange(result); 

while (result.MoreAvailable) 
{ 
    cv.StartDate = appointments.Last().Start; 

    result = cal.FindAppointments(cv); 

    appointments.AddRange(result); 
} 

Chociaż nie wiem, czy są one w porządku. Jeśli nie, możesz użyć ostatniej daty rozpoczęcia envent i usunąć duplikaty.

Powiązane problemy