Windows Azure Table storage has minimal support for LINQ queries. They support a few key operations, but a majority of the operators are unsupported. For RIA developers used to Entity Framework development, this is a significant difference. I wanted to put together this short post to draw your attention to this link.

When you use an unsupported operator, your application will fail at runtime. Typically the error is something along these lines.

An error occurred while processing this request.
at System.Data.Services.Client.DataServiceRequest.Execute[TElement](DataServiceContext context, QueryComponents queryComponents)
at System.Data.Services.Client.DataServiceQuery`1.Execute()
at System.Data.Services.Client.DataServiceQuery`1.GetEnumerator()
at SampleCloudApplication.Web.MyDomainService.GetMyParentEntitiesWithChildren()
at …

with an InnerException that looks like this.

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
  <code>NotImplemented</code>
  <message xml:lang="en-US">The requested operation is not implemented on the specified resource.</message>
</error>

To solve this problem, you will need to bring the data to the mid-tier (where your DomainService is running) using the .ToArray() method. For example, “return this.EntityContext.MyEntities.OrderBy(e => e.MyProperty)” will fail but “return this.EntityContext.MyEntities.ToArray().OrderBy(e => e.MyProperty)” will succeed.

The lack of support is an issue on the mid-tier, but has very little effect on the client. The base class, TableDomainService, does a lot of work processing the query to correctly handle most things sent from the client. The one caveat to this is some .Where filters are too complex to be processed. For example, most string operations like Contains can’t be used and string equality is case sensitive (so be sure to set FilterDescriptor.IsCaseSensitive to true when using DomainDataSource filters). Just like the other unsupported operators, you can still implement this on the mid-tier using .ToArray() before performing the complex .Where query.