我有一个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; }
}
但是,这还没有解决问题。这个错误是否在讨论我在查询中使用的类以外的其他资源?
答案 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