Azure表存储投影查询和未实现的异常

时间:2012-11-18 03:19:58

标签: azure azure-table-storage

我有一个Person类,我将其保存到Azure Table Storage中的表中。

我想使用以下查询之一查询它:

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>();

使用其中任何一个,我得到以下错误,抛出foreach循环,我用来遍历查询结果:

NotImplemented 请求的操作未在指定的资源上实现。

我认为这可能是因为我的Person模型没有从TableServiceEntity继承(我拒绝引入这种耦合 - 所以我用这个属性来装饰它:[DataServiceKey(“PartitionKey”,“RowKey”)]并手动为其指定了PartitionKey和RowKey属性。

所以我尝试创建一个DID从TableServiceEntity继承的实体,它允许我查询这个表(从查询中可以看出,我唯一担心的是Name)。

这个新实体如下:

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

但是,这还没有解决问题。这个错误是否在讨论我在查询中使用的类以外的其他资源?

1 个答案:

答案 0 :(得分:4)

这里有两个问题:

1)Azure表存储不支持Contains()方法。这就是你得到Not Implemented异常的原因。 ATS支持string.Compare()用于字符串

上的任何范围类型操作

2)为了有效地检索数据,您只能搜索PartitionKey或PartitionKey / RowKey组合。任何其他查询都会导致错误或将完整表下载到客户端的内存中(无法记住哪一个)。如果你的表很小,可以通过删除'where'子句将其完全下载到内存中,然后使用Linq for Objects查询你喜欢的内容。如果它很大,找到一种方法来比较PartitionKey或PartitionKey / RowKey字段

如果我理解您正在尝试正确执行的操作,那么您是否正在尝试通过员工表进行部分字符串搜索。总的来说,ATS对于进行基于字符串的搜索来说不是一个很好的解决方案(除非这些搜索是在“PartitionKey”或“PartitionKey / RowKey”字段上“开始”搜索)。我强烈建议Lucene.NET在云中进行基于文本的搜索。 Lucene.NET也有Azure Directory API可用。或者切换到SQL Azure

HTH