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 start with my fictitious Outlook calendar:

This calendar shows that I have four appointments today. The appointments have been categorized as either "Work" (blue) or "Personal" (green). Suppose I would like to create an Outlook add-in that displays my personal appointments on startup. I will first create a new C#-based Outlook 2007 Add-in project in Visual Studio 2008.

Next I'll add a reference to one of the Outlook extension assemblies, which were installed as part of the Office Interop API Extensions. I'll select version 12.0.0.0 of the assembly because I'm using Outlook 2007. Version 11.0.0.0 of the assembly would be used with Outlook 2003.

Before they can be used, I have to tell the compiler to look for the extensions during build. I'll do that through a set of using statements at the beginning of my source file.

Two using statements are required:

  • using Microsoft.Office.Interop.Outlook.Extensions;

    This statement brings in the Items.AsQueryable<T>() extension method that I'll use in my LINQ expression.

  • using Microsoft.Office.Interop.Outlook.Extensions.Linq;

    This statement brings in the LINQ to DASL types that form the basis for my LINQ expression.

With that, I can then write my LINQ expression in the startup event handler of the add-in:

private void ThisAddIn_Startup(object sender, System.EventArgs e)

{

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

select item.Item;

var builder = new StringBuilder();

builder.AppendLine("Personal Appointments:");

builder.AppendLine();

foreach (var appointment in appointments)

{

builder.AppendLine(appointment.Subject);

}

MessageBox.Show(builder.ToString());

}

Let's look at this query more closely. The first clause "from item in folder.Items.AsQueryable<Appointment>()" uses the new Items.AsQueryable<T> extension method. This extension method simply returns a new instance of the ItemsSource<T> class, which implements the LINQ interfaces IQueryProvider and IQueryable. I know this folder contains only appointments, so I specify the Appointment class for the generic type. The Appointment class is the LINQ to DASL class associated with the AppointmentItem interface in Outlook. If the folder contained a mixture of Outlook item types (such as both appointments and meetings), I would either need to use the more generic OutlookItem class or use the MessageClass property in my query to restrict the types of the items returned.

The second clause "where item.Categories.Contains("Personal")" is the "meat" of the query. This is the expression translated into a DASL query string and passed to Outlook. Outlook then returns a collection of Items matching the query string. In this case, I want Outlook to return only items where the categories property contains the string "Personal". The where clause can contain a number of different types of expressions:

  • The typical set of comparisons (==, !=, <, <=, >=, >, &&, ||)
  • Negation (!)
  • Method calls on properties using String.Contains(), String.StartsWith(), and String.EndsWith()
  • Expressions involving user properties (e.g. item.UserProperties["Foo"].Value)

The last clause "select item.Item" specifies what items to return from the query. LINQ to DASL will wrap each item returned by Outlook with an instance of the type specified in the AsQueryable<T>() extension method. That instance can be returned as-is, or a projection on that instance can be returned instead. I want the original AppointmentItem instance returned by Outlook so I specify a simple projection that returns the Item property on the Appointment class. The select clause also determines the ultimate type of the returned data, IEnumerable<Outlook.AppointmentItem> in this case. This is what I iterate over in my foreach loop.

Finally, I can hit 'F5' and see the results.

Hopefully this helps people get started with LINQ to DASL. (If it doesn't, please let me know what else I can cover to make things more clear.) This sample can be found on Code Gallery here.