Azure 表查询:System.InvalidOperationException:“已经有一个打开的 DataReader 与此命令关联,必须先关闭。”

Posted

技术标签:

【中文标题】Azure 表查询:System.InvalidOperationException:“已经有一个打开的 DataReader 与此命令关联,必须先关闭。”【英文标题】:Azure Table Query : System.InvalidOperationException: 'There is already an open DataReader associated with this Command which must be closed first.' 【发布时间】:2020-07-16 07:08:24 【问题描述】:

我在表执行查询期间偶尔会遇到以下错误

System.InvalidOperationException: '已经有一个打开的 DataReader 与此命令关联,必须先关闭。'

private CloudTable table;

    public AzureTableManager(string _CloudTableName)
    
        if (string.IsNullOrEmpty(_CloudTableName))
        
            throw new ArgumentNullException("Table", "Table Name can't be empty");
        
        try
        
            string ConnectionString = PrimariusOMS.Properties.Settings.Default.AzureTableStorage.ToString();
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConnectionString);
            CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

            table = tableClient.GetTableReference(_CloudTableName);
            table.CreateIfNotExists();
        
        catch (StorageException StorageExceptionObj)
        
            throw StorageExceptionObj;
        
        catch (Exception ExceptionObj)
        
            throw ExceptionObj;
        
    

    public List<T> RetrieveEntity<T>(string TenantName, string Query = null) where T : TableEntity, new()
    
TableQuery<T> DataTableQuery = new TableQuery<T>();
            if (!String.IsNullOrEmpty(Query))
            
                Query += " and PartitionKey eq '" + TenantName + "'";
            
            else  Query = "PartitionKey eq '" + TenantName + "'"; 

            DataTableQuery = new TableQuery<T>().Where(Query);
            IEnumerable<T> IDataList = table.ExecuteQuery(DataTableQuery);
            List<T> DataList = new List<T>();
            foreach (var singleData in IDataList)
                DataList.Add(singleData);
            return DataList;

此处返回错误:

IEnumerable<T> IDataList = table.ExecuteQuery(DataTableQuery);

这是我的示例调用:

List<AzureTableManager.DTTConfig> dtt = TableManagerObj.RetrieveEntity<AzureTableManager.DTTConfig>(tenantID, "RowKey eq 'Mass WhatIf'");

在 SQL 连接中,使用 USING 块或确保阅读器已关闭来克服此问题。 这里怎么处理?

【问题讨论】:

可以分享完整的代码吗?在这个问题之前,我从未见过 DataReaderCommand 使用 Azure Tables。 @GauravMantri - 添加了其余代码。这实际上是来自 Microsoft.WindowsAzure.Storage.Table 的标准调用。这里没有明确的 DataReader 调用。 感谢分享代码。你能告诉我哪一行代码引发了你得到的错误吗?另外,请分享您拨打的代码RetrieveEntity @GauravMantri 附加到我的问题中。请注意,有时每秒都会进行一次通话。 【参考方案1】:

您可以尝试将您的引用更新为最新版本的WindowsAzure.Storage

在新版本中,CloudTable 类不再包含ExecuteQuery 方法。相反,它有ExecuteQueryAsyncExecuteQuerySegmentedAsync 方法。

此代码适用于我获取数据:

public static async Task<List<T>> ExecuteQueryToListAsync<T>(this CloudTable table, TableQuery<T> query) where T : ITableEntity, new()

    var result = new List<T>();

    TableContinuationToken token = null;
    do
    
        TableQuerySegment<T> seg = await table.ExecuteQuerySegmentedAsync(query, token);
        token = seg.ContinuationToken;
        result.AddRange(seg);
    
    while (token != null);

    return result;

【讨论】:

我确实在使用最新版本 - 9.3.3,它公开了 ExecuteQuery 和 ExecuteQueryAsync。它以某种方式再次工作而无需任何代码更改,因此我无法验证您的建议。也许是时候升级到nuget.org/packages/Microsoft.Azure.Cosmos.Table

以上是关于Azure 表查询:System.InvalidOperationException:“已经有一个打开的 DataReader 与此命令关联,必须先关闭。”的主要内容,如果未能解决你的问题,请参考以下文章

Azure表存储查询使用Python-读取整数列

从 Azure 表存储的千万条记录中查询一条记录

AZURE 表存储、ODATA 和更友好的 URI 查询

如何从 azure 表存储中编写组合查询?

在 Azure 表服务 linq 查询中运行包含运算符

使用 Rest Api 查询 Azure 表存储