1

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

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

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
                        };

或者

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; }
}

然而,这并没有解决问题。这个错误是在谈论我在查询中使用的类之外​​的其他资源吗?

4

1 回答 1

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

高温高压

于 2012-11-18T03:51:31.833 回答