Question

I'm trying to query a table in Windows Azure storage and was initially using the TableQuery.CombineFilters in the TableQuery<RecordEntity>().Where function as follows:

TableQuery.CombineFilters(
    TableQuery.GenerateFilterCondition("PartitionKey",   QueryComparisons.GreaterThanOrEqual, lowDate),
    TableOperators.And,
    TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.LessThanOrEqual, lowDate),
    TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, entityId)
));

Unfortunately CombineFilters only allows 2 query criteria max. So I'm currently doing this:

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

Is there any other way of doing it. Am conerned that the way I'm doing it at present is vulnerable to changes in the way the Azure Api works.

Was it helpful?

Solution

A combined filter can then be combined with another filter, repeating as many times as necessary. See the example "Sample – Query all entities with a PartitionKey=”SamplePK” and RowKey greater than or equal to “5”" at https://docs.microsoft.com/en-us/archive/blogs/windowsazurestorage/windows-azure-storage-client-library-2-0-tables-deep-dive#querying.


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

OTHER TIPS

This is what I am using as a quick check for the range of uploaded records.

        .....

        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.....
....
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top