1

How can I fetch all emails from Exchange 2010 in the least amount of EWS calls?

Our mailbox has 50k+ emails with 2k~ folders. I've tried iterating through each folder but this takes hours to fetch all of my emails. My current approach is to fetch all folders from the mailbox then make a list of search filters essentially filtering all items that have a parent folder id of n.

Here is what I have so far.

var allFolders = exchangeService.FindFolders(folderId,
                                             new FolderView(int.MaxValue) {Traversal = FolderTraversal.Deep});
var searchFilterCollection = new List<SearchFilter>();

foreach(var folder in allFolders)
    searchFilterCollection.Add(new SearchFilter.SearchFilterCollection(LogicalOperator.Or, 
        new SearchFilter.IsEqualTo(ItemSchema.ParentFolderId, folder.Id.ToString())));

var itemView = new ItemView(int.MaxValue)
                   {
                       PropertySet = PropertySet.FirstClassProperties
                   };
var findItems = exchangeService.FindItems(folderId, 
    new SearchFilter.SearchFilterCollection(LogicalOperator.Or, searchFilterCollection), itemView);

The error I receive it The property can not be used with this type of restriction..

gcso
  • 2,315
  • 3
  • 28
  • 50

3 Answers3

2

If you use EWS directly instead of the EWS Managed API, you can use the FindItemOperation to do this. The EWS FindItemOperation takes multiple parentFolderIds as input.

http://msdn.microsoft.com/en-us/library/aa566107(v=exchg.140).aspx

Henning Krause
  • 5,302
  • 3
  • 24
  • 37
1

http://social.technet.microsoft.com/Forums/en-US/exchangesvrdevelopment/thread/4bd4456d-c859-4ad7-b6cd-42831f4fe7ec/

This seems to say that ParentFolderId cannot be accessed in your filter because it is not yet loaded.

You can instruct EWS to load it by adding it to your FolderView:

FolderView view = new FolderView(int.MaxValue) {Traversal = FolderTraversal.Deep};
view.PropertySet.Add(FolderSchema.ParentFolderId);
var allFolders = exchangeService.FindFolders(folderId,view);
sq33G
  • 3,320
  • 1
  • 23
  • 38
0

As an alternative to search in a mailbox you can use the AllItems folder and do a searchfilter using the MAPI Property "PR_PARENT_ENTRYID" - https://technet.microsoft.com/de-de/sysinternals/gg158149.

// use MAPI property from Items parent entry id
ExtendedPropertyDefinition MAPI_PARENT_ENTRYID = new ExtendedPropertyDefinition(0x0E09, MapiPropertyType.Binary);

// get the "AllItems" folder from its account
folderResult = service.FindFolders(WellKnownFolderName.Root, new SearchFilter.IsEqualTo(FolderSchema.DisplayName, "allitems"), folderView);
var allItemsFolder = folderResult.FirstOrDefault();

// convert EWS Folder Id to MAPI ENTRYID - parentFolderId is us an AlternateId
var convertedId = service.ConvertIds(parentFolderId, IdFormat.EntryId);

// use the MAPI Property with its converted PARENT_ENTRY_ID in EWS Searchfilters
var parent_entry_id = (ids.ConvertedId as AlternateId).UniqueId;
var searchFilterFolders = new SearchFilter.IsEqualTo(MAPI_PARENT_ENTRYID, parent_entry_id);

// search in "AllItems" using the searchFilter containing the converted PARENT_ENTRY_ID
result = service.FindItems(folderId, searchFilterFolders, view);
Ole K
  • 754
  • 1
  • 9
  • 32