سؤال

I need to modify and existing Azure Table Storage query, assuming i is an integer query retrieves latest report:

string rowCompare = String.Format(CommonDefs.inverseTimeStampRowKeyFormat, DateTime.MaxValue.Ticks - DateTime.UtcNow.Ticks);
var result = (from er in this.serviceContext.EntityReportsTable
                           where er.PartitionKey.Equals(i.ToString(), StringComparison.OrdinalIgnoreCase) && er.RowKey.CompareTo(rowCompare) > 0
                           select er).Take(1)).FirstOrDefault();

I need to modify it to retrieve latest reports for several known entities, replacing single integer i with array of integers - like int[]{1, 6, 10}.

Apart from running existing query sequentially for the each parameter in array, is there a way to do it in one query? Like IN clause in Sql?

هل كانت مفيدة؟

المحلول

You can use the lastest version of the Azure Storage Client Library this is the complete pseudo code for your task:

var rowCompare = String.Format("{0}", DateTime.MaxValue.Ticks - DateTime.UtcNow.Ticks);
var items = new []{"1", "6", "10"};

var filters =
    items.Select(key => TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, key)).ToArray();

var combine =
    filters.Length > 0
        ? filters[0]
        : null;

for (var k = 0; k < filters.Length; k++)
    combine = TableQuery.CombineFilters(combine, TableOperators.Or, filters[k]);

var final = TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.GreaterThan, rowCompare);
if (!string.IsNullOrEmpty(combine))
    final = TableQuery.CombineFilters(final, TableOperators.And, combine);

var query = new TableQuery<EntityReport>().Where(final);

var client = CloudStorageAccount.DevelopmentStorageAccount.CreateCloudTableClient();
var table = client.GetTableReference("EntityReports");
var result = table.ExecuteQuery(query);

نصائح أخرى

Azure Table Storage does not support IN clause like SQL. However instead of doing a query sequentially, you could fire queries in parallel and compare the result. For example look at the pseudo code below:

        List<Task<T>> tasks = new List<Task<T>>();
        foreach (var i in integerArray)
        {
            tasks.Add(Task.Factory.StartNew<T>(() => {
                string rowCompare = String.Format(CommonDefs.inverseTimeStampRowKeyFormat, DateTime.MaxValue.Ticks - DateTime.UtcNow.Ticks);
                var result = (from er in this.serviceContext.EntityReportsTable
                                           where er.PartitionKey.Equals(i.ToString(), StringComparison.OrdinalIgnoreCase) && er.RowKey.CompareTo(rowCompare) > 0
                                           select er).Take(1)).FirstOrDefault();
            }));
        }
        Task.WaitAll(tasks.ToArray());
        foreach (var task in tasks)
        {
            var queryResult = task.Result;
            //Work on the query result
        }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top