如何异步执行Azure表存储查询?客户端版本4.0.1

本文关键字:客户端 查询 版本 存储 何异步 异步 Azure 执行 | 更新日期: 2023-09-27 18:08:55

想要在Azure Storage Client Version 4.0.1上异步执行查询

没有ExecuteQueryAsync()方法

我错过了什么?我们应该继续使用ExecuteQuerySegmentedAsync吗?谢谢。

如何异步执行Azure表存储查询?客户端版本4.0.1

我最后做了一个扩展方法来使用ExecuteQuerySegmentedAsync。我不确定这个解决方案是否是最佳的,如果有人有任何意见,请不要犹豫。

public static async Task<IList<T>> ExecuteQueryAsync<T>(this CloudTable table, TableQuery<T> query, CancellationToken ct = default(CancellationToken), Action<IList<T>> onProgress = null) where T : ITableEntity, new()
    {
        var items = new List<T>();
        TableContinuationToken token = null;
        do
        {
            TableQuerySegment<T> seg = await table.ExecuteQuerySegmentedAsync<T>(query, token);
            token = seg.ContinuationToken;
            items.AddRange(seg);
            if (onProgress != null) onProgress(items);
        } while (token != null && !ct.IsCancellationRequested);
        return items;
    }

当表查询包含take子句时,解决方案将返回比查询请求更多的项。只要稍微改变一下while表达式就可以解决这个问题。

public static async Task<IList<T>> ExecuteQueryAsync<T>(this CloudTable table, TableQuery<T> query, CancellationToken ct = default(CancellationToken), Action<IList<T>> onProgress = null) where T : ITableEntity, new()
{
    var runningQuery = new TableQuery<T>()
    {
        FilterString = query.FilterString,
        SelectColumns = query.SelectColumns
    };
    var items = new List<T>();
    TableContinuationToken token = null;
    do
    {
        runningQuery.TakeCount = query.TakeCount - items.Count;
        TableQuerySegment<T> seg = await table.ExecuteQuerySegmentedAsync<T>(runningQuery, token);
        token = seg.ContinuationToken;
        items.AddRange(seg);
        if (onProgress != null) onProgress(items);
    } while (token != null && !ct.IsCancellationRequested && (query.TakeCount == null || items.Count < query.TakeCount.Value));
    return items;
}

EDITED:由于PaulG的建议,更正了查询包含take子句和ExecuteQuerySegmentedAsync在几次传递中返回项时结果计数的问题。

这是对@JoseCh.答案的补充。

这是一个扩展方法,它允许你指定一个EntityResolver:

public static async Task<IList<TResult>> ExecuteQueryAsync<T, TResult>(this CloudTable table, TableQuery query, EntityResolver<TResult> resolver, Action<IList<TResult>> onProgress = null, CancellationToken cancelToken = default(CancellationToken))
            where T : ITableEntity, new()
{
    var items = new List<TResult>();
    TableContinuationToken token = null;
    do
    {
        TableQuerySegment<TResult> seg = await table.ExecuteQuerySegmentedAsync(query: query, resolver: resolver, token: new TableContinuationToken(), cancellationToken: cancelToken).ConfigureAwait(false);
        token = seg.ContinuationToken;
        items.AddRange(seg);
        onProgress?.Invoke(items);
     }
     while (token != null && !cancelToken.IsCancellationRequested);
         return items;
     }
}

如果您只想返回存储中单个列的结果集,可以使用:

// maps to a column name in storage
string propertyName = nameof(example.Category);
// Define the query, and select only the Category property.
var projectionQuery = new TableQuery().Select(new string[] { propertyName });
// Define an entity resolver to work with the entity after retrieval.
EntityResolver<string> resolver = (pk, rk, ts, props, etag) => props.ContainsKey(propertyName) ? props[propertyName].StringValue : null;
var categories = (await someTable.ExecuteQueryAsync<DynamicTableEntity, string>(query: projectionQuery, resolver: resolver).ConfigureAwait(false)).ToList()