如何在C#中获取Azure表存储中的所有行?

61

我想获取Azure表中所有实体的列表。

有什么想法可以编写这个查询吗?


你是否在使用任何语言特定的库,例如 .Net 存储客户端库? - Gaurav Mantri
我正在使用Microsoft.WindowsAzure.Storage库。 - SKLAK
3个回答

118

为了回答您的问题,您可以尝试以下操作:

var acc = new CloudStorageAccount(
                         new StorageCredentials("account name", "account key"), true);
var tableClient = acc.CreateCloudTableClient();
var table = tableClient.GetTableReference("table name");
var entities = table.ExecuteQuery(new TableQuery<MyEntity>()).ToList();

请注意,表格服务在单次调用中最多返回1000个实体。如果您的表中有超过1000个实体可用,则会返回一个“续标记”,该标记可用于获取下一组实体。实际上,ExecuteQuery方法在内部处理此续标记,因此如果您想出于任何原因取消此操作,则不能这样做。

更好的方法是使用ExecuteQuerySegmented方法,并让您的应用程序处理令牌。以下是示例代码:

var acc = new CloudStorageAccount(
                         new StorageCredentials("account name", "account key"), true);
var tableClient = acc.CreateCloudTableClient();
var table = tableClient.GetTableReference("table name");
TableContinuationToken token = null;
var entities = new List<MyEntity>();
do
{
    var queryResult = table.ExecuteQuerySegmented(new TableQuery<MyEntity>(), token);
    entities.AddRange(queryResult.Results);
    token = queryResult.ContinuationToken;
} while (token != null);

4
我只能从中获得PartitionKey和RowKey。如果想获取所有属性,需要添加:"var entities = table.ExecuteQuery(new TableQuery<MyModel>()).ToList();"(添加<MyModel>)。这对我来说不是很明显 :) - mathkid91
1
在这种情况下,MyEntity是我们自己的类?那么它的getter或setter将是什么? - lokanath das
对于两个示例代码的第一行使用“false”有些困惑 - 明确一下,您是在主动禁用连接上的HTTPS,对吗?为什么将其限制为HTTP会有好处呢? - Brett Rigby
@BrettRigby...你说得对。让流量通过http是个坏主意。我已经修复了代码。感谢你提醒我。 - Gaurav Mantri

10

如果您不需要每次都获取全部行,那么通过使用 yield 来按需(惰性地)检索项目更加高效:

public async Task<IEnumerable<T>> GetAll<T>(string tableName) where T : class
{
    var table = this.GetCloudTable(tableName);
    TableContinuationToken token = null;
    do
    {
        var q = new TableQuery<T>();
        var queryResult = await table.ExecuteQuerySegmentedAsync(q, token);
        foreach (var item in queryResult.Results)
        {
            yield return item;
        }
        token = queryResult.ContinuationToken;
    } while (token != null);
}

采用这种方法,您可以获取所有行,但是如果您正在遍历GetAll()的结果并找到所需内容,则可以直接使用break退出循环,而GetAll()方法将停止检索表中的下一行。


7

使用更新的 Azure.Data.Tables SDK,特别是在使用 System.Linq.Async nuget 包时,这将变得更加简短。使用该包后,您只需编写:

/// <summary>
/// Returns all rows in the table
/// </summary>
/// <typeparam name="T">Implementation of ITableEntity</typeparam>
/// <param name="tableClient">The authenticated TableClient</param>
/// <returns></returns>
public static async Task<List<T>> GetAllEntitiesAsync<T>(this TableClient tableClient) where T : class, ITableEntity, new()
{
    return await tableClient.QueryAsync<T>(maxPerPage: 1000).ToListAsync().ConfigureAwait(false);
}

注意:一次请求1000行(最大值)可以大大减少总请求次数。 来源

1
非常感谢您!我是Azure Functions和Azure Table Storage的新手。我对CloudTable、ClientTable、不同的库等感到困惑。这对我帮助很大! - MuhKuh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接