想要在Azure存储客户端版本4.0.1上执行查询异步
没有方法ExecuteQueryAsync()..
我错过了什么?我们应该继续使用ExecuteQuerySegmentedAsync吗? 感谢。
答案 0 :(得分:68)
我最终制作了一个扩展方法来使用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;
}
答案 1 :(得分:14)
当表查询包含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;
}
已编辑:感谢PaulG的建议,当查询包含take子句时,更正了结果计数的问题,ExecuteQuerySegmentedAsync
会在多次传递中返回项目。
答案 2 :(得分:0)
这是@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()