如何使用 TableClient.QueryAsync 指定 Take 值

问题描述 投票:0回答:3

我正在更新我的项目以使用

Azure.Data.Tables
12.6.1,但我不知道在哪里指定
Take
值来限制从查询返回的实体数量。

换句话说,我想做这样的事情:

var limit = 150;
var results = table.QueryAsync<T>(limit);
await foreach (var page in results.AsPages().ConfigureAwait(false)) {
    // Regardless of how the server pages the results, 
    // only the top [limit] items are returned.
}

在旧 API 中,您可以在查询对象上设置

Take
属性。我该如何在新 API 中执行此操作?

azure-storage azure-table-storage azure-tablequery
3个回答
2
投票

正如 @Skin 指出的,当前的 SDK 并未公开

Take
的显式 API,但这是一个有意的决定,以确保开发人员更清楚从服务角度来看到底发生了什么。

旧的 SDK 支持完整的

IQueryable
API,这使得创建非常昂贵的查询变得很容易,这些查询在从服务获取整个表后执行过滤客户端。

虽然

Take
没有与其他 Linq 方法相同的问题,但该服务并不真正支持它。它只能限制分页结果的数量(服务上限为 1000)。

虽然我同意它不像 Take API 那么简单,但当前的 API 使得实现等效功能变得相当简单,同时不会隐藏您实际上可能从服务中获取超出 Take 限制的事实。

此示例演示了如何使用每页最大项目集来迭代页面。


1
投票

这可能有点争议,但我将把它添加为答案......看起来它只是几周前作为功能请求提出的,现在已添加到待办事项中......

https://github.com/Azure/azure-sdk-for-net/issues/30985

您不是唯一有相同要求的人。


0
投票

当限制低于 1000 Azure max 时,使用显式限制,当限制为 1000+ 时,计算有多少页并在达到计数时停止,然后修剪到精确计数。

当查询找到 5000 个且您想要的限制为 1001 时,最大开销将为 999,因为您将下载 2000 个项目并截断 999。当您的限制为 < 1000 you pull only 1 page with exact count of items (no ovearhaed).

理论上你可以进行复杂的 maxPerPage 计算,但这没有意义,HTTP 在延迟方面的成本更高,尤其是在移动设备上,因此最好少发出最大可能页面的请求,而不是更多较小页面的请求。

public async Task<IEnumerable<T>> QueryAsyncLimit<T>(string tableName, string filter, IEnumerable<string> select, int limit) where T : class, ITableEntity, new()
{
    var tableClient = ...;
    var entities = new List<T>();
    var maxPerPage = limit < 1000 ? limit : 1000; // Azure page default is 1000 and it's max
    var pages = tableClient.QueryAsync<T>(filter, maxPerPage, select).AsPages();
    var currentPage = 1;

    await foreach (var page in pages)
    {
        entities.AddRange(page.Values);
        if (currentPage == GetPageCount(limit))
            break; //stop "downloading" pages
        currentPage++;
    }
    return entities.Take(limit); //cut off the excess when more than 1 page
}


private int GetPageCount(int limit)
{
    int pageSize = 1000; // Azure page default is 1000 and it's max
    int pageCount = (int)Math.Ceiling((double)limit / pageSize);
    return pageCount;
}
© www.soinside.com 2019 - 2024. All rights reserved.