1
votes

I have a Person class that I save to a table in Azure Table Storage.

I want to query it with one of the following queries:

var query = from getThis in _serviceContext.CreateQuery<PersonForSearch>(_tableName)
                        where getThis.Name.Contains(searchTerm)
                        select new Person
                        {
                            PartitionKey = getThis.PartitionKey, 
                            RowKey = getThis.RowKey,
                            Name = getThis.Name
                        };

OR

CloudTableQuery<Person> query =
                 (from getThis in _serviceContext.CreateQuery<Person>(_tableName)
                  where getThis.Name.Contains(searchTerm)
                  select getThis).AsTableServiceQuery<Person>();

With either one, I get the following error, thrown on the foreach loop I use to loop through the results of the query:

NotImplemented The requested operation is not implemented on the specified resource.

I thought that perhaps this resulted from the fact that my Person model does not inherit from TableServiceEntity (I refuse to introduce that coupling - so I decorated it with this attribute instead: [DataServiceKey("PartitionKey", "RowKey")] and manually gave it a PartitionKey and RowKey property.

So I tried to create an entity that DID inherit from TableServiceEntity, which would allow me to query this table (as you can see from the queries, the only property I'm worried about is Name).

This new entity is as follows:

class PersonForSearch : TableServiceEntity
{
    public string Name { get; set; }
}

However, this hasn't solved the problem. Is this error talking about some other resource than the class I'm using in my query?

1

1 Answers

4
votes

There are a two issues here:

1) Azure Table Storage does not support Contains() method. This is the reason you're getting Not Implemented exception. ATS does support string.Compare() for any range-type operations on strings

2) In order to retrieve the data effectively, you can only search on PartitionKey or on PartitionKey/RowKey combination. Any other query will result in either errors or the download of the full table into client's memory (can't remember which one). If your table is small, download it into memory completely by dropping the 'where' clause and afterwards use Linq for Objects to query however you like. If it is large, find a way to compare against PartitionKey or PartitionKey/RowKey fields

If I'm understanding what you're trying to do correctly, is that you're trying to do a partial string-search through employee table. Overall, ATS is not a very good solution for doing string-based searches (unless these are "starts with" searches on PartitionKey or PartitionKey/RowKey fields). I'd like to highly recommend Lucene.NET for doing text-based searches in the cloud. There is an Azure Directory API for Lucene.NET available as well. Or switch to SQL Azure

HTH