Запрос хранилища таблиц Windows Azure с несколькими критериями запроса
Я пытаюсь запросить таблицу в хранилище Windows Azure и изначально использовал TableQuery.CombineFilters
в функции TableQuery<RecordEntity>().Where
следующим образом:
TableQuery.CombineFilters(
TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.GreaterThanOrEqual, lowDate),
TableOperators.And,
TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.LessThanOrEqual, lowDate),
TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, entityId)
));
К сожалению, CombineFilters допускает только 2 критерия запроса max. Поэтому я сейчас делаю это:
var tableQuery = new TableQuery<RecordRowEntity>()
.Where(TableQuery.CombineFilters("PartitionKey", string.Format("(PartitionKey ge '{0}') and (PartitionKey le '{1}') and (RowKey eq '{2}')", low, high, entityId));
Есть ли другой способ сделать это. Меня беспокоит то, что способ, которым я это делаю в настоящее время, уязвим для изменений в работе Azure Api.
Ответы
Ответ 1
Затем объединенный фильтр можно комбинировать с другим фильтром, повторяя столько раз, сколько необходимо. См. Пример "Образец - запрос всех объектов с PartitionKey =" SamplePK "и RowKey, которые больше или равны" 5 "на http://blogs.msdn.com/b/windowsazurestorage/archive/2012/11/06/windows-azure-storage-client-library-2-0-tables-deep-dive.aspx,
string pkFilter = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "samplePK");
string rkLowerFilter = TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.GreaterThanOrEqual, "5");
string rkUpperFilter = TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.LessThan, "10");
// Note CombineFilters has the effect of "([Expression1]) Operator (Expression2]), as such passing in a complex expression will result in a logical grouping.
string combinedRowKeyFilter = TableQuery.CombineFilters(rkLowerFilter, TableOperators.And, rkUpperFilter);
string combinedFilter = TableQuery.CombineFilters(pkFilter, TableOperators.And, combinedRowKeyFilter);
// OR
string combinedFilter = string.Format("({0}) {1} ({2}) {3} ({4})", pkFilter, TableOperators.And, rkLowerFilter, TableOperators.And, rkUpperFilter);
TableQuery query = new TableQuery().Where(combinedFilter);
Ответ 2
Это то, что я использую для быстрой проверки диапазона загруженных записей.
.....
Dictionary<int, string[]> retrievedRecords = new Dictionary<int, string[]>();
int i = 0;
StorageCredentials creds = new StorageCredentials(accountName, accountKey); // table storage name, Azure provided KEY1 string
CloudStorageAccount storageAccount = new CloudStorageAccount(creds, useHttps: true);
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
CloudTable table = tableClient.GetTableReference(tableName); // your table name
// filters
string filter1 = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partitionName); // partitionName i.e.: "myTablePartition1"
string filter2 = TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.GreaterThanOrEqual, recordStart); // recordStart i.e.: "123"
string filter3 = TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.LessThan, recordEnd); // recordEnd i.e.: "567"
string filterRange = TableQuery.CombineFilters(filter2, TableOperators.And, filter3);
// query.
TableQuery<CustomerEntity> rangeQuery = new TableQuery<CustomerEntity>().Where(
TableQuery.CombineFilters(filter1, TableOperators.And, filterRange)
);
// Loop & store
foreach (CustomerEntity entityT in table.ExecuteQuery(rangeQuery))
{
string PartitionKey = entityT.PartitionKey;
string RowKey = entityT.RowKey;
string col1 = entityT.col1;
string col2 = entityT.col2;
string col3 = entityT.col3;
string col4 = entityT.col4;
string col5 = entityT.col5;
string col6 = entityT.col6;
string[] row = new string[] { PartitionKey, RowKey, col1 , col2, col3, col4, col5, col6 };
retrievedRecords.Add(i, row);
i++;
}
return retrievedRecords;
// function end or else.....
....