Deleting calendar events with Microsoft Graph - Wh

2019-07-23 19:15发布

问题:

After much investigation and beta-testing I have come up with the following approach to delete calendar events:

public async Task<bool> DeleteCalendarEvents(SettingsBase oSettings, string valueProperty1, string valueProperty2)
{
    string strFilterDateRange = String.Format("start/dateTime ge '{0}T00:00' and end/dateTime le '{1}T23:59'",
    oSettings.StartDate.ToString("yyyy-MM-dd"),
    oSettings.EndDate.ToString("yyyy-MM-dd"));

    // Filter the events on the TruckleSoft1 property
    string strFilterProperty1 = $"singleValueExtendedProperties/Any(ep: ep/id eq '{SettingsBase.Property_TruckleSoft1}' and ep/value eq '{valueProperty1}')";

    // Build the filter
    string strFilter = $"{strFilterDateRange} and {strFilterProperty1}";

    // Filter the events on the TruckleSoft2 property (this is optional)
    if (valueProperty2 != "")
    {
        string strFilterProperty2 = $"singleValueExtendedProperties/Any(ep: ep/id eq '{SettingsBase.Property_TruckleSoft2}' and ep/value eq '{valueProperty2}')";

        // Update the filter
        strFilter += $" and {strFilterProperty2}";
    }


    var oCalendar = await _graphClient.Me.Calendars[oSettings.CalendarID].Request().GetAsync();
    string strName = oCalendar.Name;


    var oEvents = await _graphClient
                            .Me
                            .Calendars[oSettings.CalendarID]
                            .Events
                            .Request()
                            .Filter(strFilter)
                            .OrderBy("start/DateTime")
                            .GetAsync();

    Program.file.WriteLine($"Calendar {strName}");
    int iPage = 0, iTotal = 0, iLoop = 0;
    bool bDeleted = false;

    do
    {
        iLoop++;

        if (oEvents?.Count > 0)
        {
            iPage++;

            foreach(Event oEvent in oEvents)
            {
                Program.file.WriteLine($"Loop {iLoop} Page {iPage} Count {oEvents.Count.ToString()} Event Data: {oEvent.Start.DateTime} Id: {oEvent.Id} Subject: {oEvent.Subject}");
                await _graphClient.Me.Events[oEvent.Id].Request().DeleteAsync();
                bDeleted = true;
            }

            iTotal += oEvents.Count;
        }

        if (oEvents.NextPageRequest != null)
            oEvents = await oEvents.NextPageRequest.GetAsync();
        else
        {
            oEvents = null;
        }
    } while (oEvents != null);

    Program.file.WriteLine($"Count: {iTotal}" + Environment.NewLine);

    return bDeleted;
}

However, the above needs to be called like this:

bool bContinue = await oOutlook.DeleteCalendarEvents(_DataSRR.SettingsSRR, _DataSRR.SettingsSRR.CalendarEntryType, _DataSRR.SettingsSRR.ScheduleType);
while(bContinue)
    bContinue = await oOutlook.DeleteCalendarEvents(_DataSRR.SettingsSRR, _DataSRR.SettingsSRR.CalendarEntryType, _DataSRR.SettingsSRR.ScheduleType);

The results in my log:

Calendar Test 5
Loop 1 Page 1 Count 10 Event Data: 09/21/2017 19:15:00 Id: AA== Subject: Midweek Meeting Duty Assignments
Loop 1 Page 1 Count 10 Event Data: 09/24/2017 13:00:00 Id: AA== Subject: Weekly Meeting Duty Assignments
Loop 1 Page 1 Count 10 Event Data: 09/28/2017 19:15:00 Id: AA== Subject: Midweek Meeting Duty Assignments
Loop 1 Page 1 Count 10 Event Data: 10/01/2017 13:00:00 Id: AA== Subject: Weekly Meeting Duty Assignments
Loop 1 Page 1 Count 10 Event Data: 10/05/2017 19:15:00 Id: AA== Subject: Midweek Meeting Duty Assignments
Loop 1 Page 1 Count 10 Event Data: 10/08/2017 13:00:00 Id: AA== Subject: Weekly Meeting Duty Assignments
Loop 1 Page 1 Count 10 Event Data: 10/12/2017 19:15:00 Id: AA== Subject: Midweek Meeting Duty Assignments
Loop 1 Page 1 Count 10 Event Data: 10/15/2017 13:00:00 Id: AA== Subject: Weekly Meeting Duty Assignments
Loop 1 Page 1 Count 10 Event Data: 10/19/2017 19:15:00 Id: AA== Subject: Midweek Meeting Duty Assignments
Loop 1 Page 1 Count 10 Event Data: 10/22/2017 13:00:00 Id: AA== Subject: Weekly Meeting Duty Assignments
Count: 10

Calendar Test 5
Loop 1 Page 1 Count 2 Event Data: 10/26/2017 19:15:00 Id: AQ== Subject: Midweek Meeting Duty Assignments
Loop 1 Page 1 Count 2 Event Data: 10/29/2017 13:00:00 Id: AQ== Subject: Weekly Meeting Duty Assignments
Count: 2

Calendar Test 5
Count: 0

As you can see, I have to make my call multiple times. Eventually it clears out all agreed events. But why can't it do this with one iteration?

回答1:

If I use the $top option I can adjust the size of the pages and thus reduce the number of calls I need to make:

List<QueryOption> listQueryOptions = new List<QueryOption>()
{
    new QueryOption("$top", "50")
};

var oEvents = await _graphClient
                        .Me
                        .Calendars[oSettings.CalendarID]
                        .Events
                        .Request(listQueryOptions)
                        .Filter(strFilter)
                        .OrderBy("start/DateTime")
                        .GetAsync();

This can be simplified that further:

var oEvents = await _graphClient
                        .Me
                        .Calendars[oSettings.CalendarID]
                        .Events
                        .Request()
                        .Top(50)
                        .Filter(strFilter)
                        .OrderBy("start/DateTime")
                        .GetAsync();

This resource was very handy. In the end I have:

public async Task<bool> DeleteCalendarEvents(SettingsBase oSettings)
{
    try
    {
        var oEvents = await _graphClient
                                .Me
                                .Calendars[oSettings.CalendarID]
                                .Events
                                .Request()
                                .Select("Start,Subject,Id") // TODO: Is there any point doing this?
                                .Top(50)
                                .Filter(oSettings.GetFilterString())
                                .OrderBy("start/DateTime")
                                .GetAsync();

        List<Event> listEvents = new List<Event>();

        listEvents.AddRange(oEvents);
        while(oEvents.NextPageRequest != null)
        {
            oEvents = await oEvents.NextPageRequest.GetAsync();
            listEvents.AddRange(oEvents);
        }

        foreach(Event oEvent in listEvents)
        { 
            await _graphClient.Me.Events[oEvent.Id].Request().DeleteAsync();
        }

    }
    catch(Exception ex)
    {
        SimpleLog.Log(ex);
        Console.WriteLine("DeleteCalendarEvents: See error log.");
        return false;
    }

    return true;
}