Filter Outlook Items by Date with LINQ to DASL

I received an email over the weekend asking why the following LINQ to DASL query threw an exception:

Outlook.Folder folder = (Outlook.Folder)Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);

var appointments =

from item in folder.Items.AsQueryable<Appointment>()

where item.Categories.Contains("Personal Appointments") && item.Item.Start.Date >= DateTime.Now - new TimeSpan(30, 0, 0, 0)

select item.Item;

foreach (var appointment in appointments)

{

MessageBox.Show(appointment.Start.ToString());

}

The query looks simple enough—return all personal appointments for the last 30 days—but when the foreach loop executes a MissingPropertyAttributeException is thrown stating "The property Date on class DateTime does not have an attached OutlookItemUserPropertyAttribute". The problem here is that (as the exception indicates) the Appointment.Item.Start.Date property does not have an OutlookItemProperty or OutlookItemUserProperty attached. These attributes are used by LINQ to DASL to map properties defined on .NET classes to DASL properties defined by Outlook. Why doesn't this attribute exist? Appointment.Item is of type Microsoft.Office.Interop.Outlook.AppointmentItem. This type is part of the Outlook object model and defined by the Outlook PIA. Unfortunately, since we have no control over the Office PIAs, we can't markup the types with our LINQ to DASL attributes. This means that we can't directly query properties on Outlook items. Instead, we query properties on a proxy class (i.e. Appointment) that we do have control over.

But wait a minute…the Appointment class doesn't have a Start property! Yes, unfortunately we weren't able to map every known DASL property to its Outlook item equivalent for this initial release (only so many hours in the day and all that). We did, however, provide a way for you to add such properties yourself.

internal class MyAppointment : Appointment

{

[OutlookItemProperty("urn:schemas:calendar:dtstart")]

public DateTime Start { get { return Item.Start; } }

[OutlookItemProperty("urn:schemas:calendar:dtend")]

public DateTime End { get { return Item.End; } }

}

The MyAppointment class above derives from the existing Appointment class and adds two new properties, Start and End. These properties simply defer to the inner Item's Start and End properties. Each property has an OutlookItemPropertyAttribute attached that maps the property to its corresponding DASL property, which can be found using the handy SQL tab of Outlook's custom filter dialog. Next, the query can be revised as follows:

Outlook.Folder folder = (Outlook.Folder)Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderCalendar);

var appointments =

from item in folder.Items.AsQueryable<MyAppointment>()

where item.Categories.Contains("Personal Appointments") && item.Start >= DateTime.Now - new TimeSpan(30, 0, 0, 0)

select item.Item;

foreach (var appointment in appointments)

{

MessageBox.Show(appointment.Start.ToString());

}

Note that the AsQueryable<T>() extension method now uses the new MyAppointment type and that its Start property is used instead of Item.Start.Date. Run the query again and Outlook should return a collection of appointments instead of an exception (presuming you have any appointments which match the query).

This post was migrated from my MSDN blog, Visual Studio Tools and Anything Else I Can Think Of, and written as a Microsoft employee.

2014

Back to Top ↑

2012

Back to Top ↑

2008

Finding DASL Property Names

1 minute read

The LINQ-to-DASL provider of the Office Interop API Extensions provides a very limited set of mappings between its query types and their associated DASL prop...

Debugging LINQ-to-DASL Queries

3 minute read

When your LINQ-to-DASL queries do not return the results you expect, how do you determine where the problem is?  The issue could be that the query simpl...

LINQ to DASL Walkthrough

3 minute read

Now that the Office Interop API Extensions have been released, I thought I would post a complete walkthrough of a simple LINQ to DASL application. Let's star...

Office Interop API Extensions Now Available!

less than 1 minute read

As announced in Andrew Whitechapel’s post, version 1.0 of the VSTO Power Tools have been released! One of those tools is the Office Interop API Extensions, a...

Using LINQ with the Office Object Model

3 minute read

In my last post I talked about LINQ to DASL, a LINQ provider that converts query expressions into their DASL equivalent in order to efficiently filter item c...

Back to Top ↑

2007

VSTO at Portland Code Camp v3.0

less than 1 minute read

Yesterday I gave a presentation on VSTO at the third annual Portland Code Camp. I demonstrated an Outlook 2007 add-in that used Outlook Form Regions, WCF, an...

Back to Top ↑