【问题标题】:receive a large amount of data from Azure Storage and process it从 Azure Storage 接收大量数据并进行处理
【发布时间】:2019-06-18 05:42:41
【问题描述】:

我需要将一些数据从 Azure 存储迁移到 Sql db。

我有以下代码:

class AzureDataAccessManager : IAzureDataAccessManager
{
    private readonly CloudTable tableClient;

    private readonly CloudStorageAccount storageAccount;

    public string TableName { get; }

    public AzureDataAccessManager(string connectionString, string tableName)
    {
        TableName = tableName ?? throw new ArgumentNullException(nameof(tableName));

        if (connectionString == null) throw new ArgumentNullException(nameof(connectionString));

        storageAccount = CloudStorageAccount.Parse(connectionString);

        tableClient = storageAccount.CreateCloudTableClient().GetTableReference(TableName);
    }

    public List<T> QueryAllRecords<T>() where T : class, ITableEntity, new()
    {
        TableContinuationToken token = null;

        var entities = new List<T>();
        do
        {
            var queryResult = tableClient.ExecuteQuerySegmented(new TableQuery<T>(), token);
            entities.AddRange(queryResult.Results);
            token = queryResult.ContinuationToken;

        } while (token != null);

        return entities;
    }
}

我得到了所有这样的记录:

var result = azureTableManager.QueryAllRecords<AzureCpaDataEntity>();

问题是我不知道那里会有多少行。如果它太大怎么办?也许可以通过一些范围(10 000 或其他),但正如我所见,List 中没有相应的方法。

请帮我提供一些解决方案或想法!

谢谢!

【问题讨论】:

  • 而不是从QueryAllRecords 方法返回所有实体,您实际上应该返回最多1000 个实体和延续令牌的查询结果。处理该数据,然后通过传递延续令牌再次为下一组实体调用此方法。
  • 您使用的查询返回分页结果。这就是为什么它被称为“ExecuteQuerySegmented”。分页是默认的,通常是云提供商的唯一选项,正是因为它们处理大量对象。 10K 太少了,一个容器可能包含数百万个对象。
  • 如果您检查the method's documentation,您会看到所有重载都接受一个延续令牌。结果类本身TableQuerySegment 有一个ContinuationToken 属性,其值应该用于获取下一个 批结果
  • @PanagiotisKanavos 谢谢,试试看!
  • @PanagiotisKanavos 如果 List 会超载怎么办?我该如何处理?

标签: c# .net list azure azure-storage


【解决方案1】:

问题的代码已经批量检索结果。无需等待所有它们到达,该方法可以变成一个迭代器并立即返回每个批次:

public IEnumerable<List<T>> QueryRecords<T>() where T : class, ITableEntity, new()
{
    TableContinuationToken token = null;

    do
    {
        var queryResult = tableClient.ExecuteQuerySegmented(new TableQuery<T>(), token);
        token = queryResult.ContinuationToken;
        yield return queryResult.Results;

    } while (token != null);
}

结果也要分批处理:

foreach(var batch in QueryRecords<AzureCpaDataEntity>())
{
    ProcessTheBatch(batch);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-27
    • 1970-01-01
    • 1970-01-01
    • 2012-10-07
    • 1970-01-01
    • 1970-01-01
    • 2011-05-22
    相关资源
    最近更新 更多