【问题标题】:TableQuery<T> from Azure TableStorage that filters on PartitionKey来自 Azure TableStorage 的 TableQuery<T> 过滤 PartitionKey
【发布时间】:2012-11-08 22:10:07
【问题描述】:

我正在尝试通过 partitionKey 从表中抽象获取所有实体,如下所示:

public List<T> GetEntities<T>(string partitionKey, T entity) where T : TableEntity
    {
        try
        {
            var tableClient = _account.CreateCloudTableClient();
            var table = tableClient.GetTableReference(entity.GetType().Name.ToLower());
            var exQuery =
                new TableQuery<T>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal,
                                                                             partitionKey));

            var results = table.ExecuteQuery(exQuery).Select(ent => (T) ent).ToList();
            return results;
        }
        catch (StorageException ex)
        {
            //TODO: Add more trace info
            Trace.TraceInformation("Unable to retrieve entity based on query specs");
            return null;
        }
    }

然而,它在

上失败了
new TableQuery<T>

因为 TElement 没有无参数构造函数。

【问题讨论】:

    标签: c# azure azure-storage azure-table-storage


    【解决方案1】:

    正如您在问题中还提到的,T 必须有一个无参数的构造函数。因此,请将您的方法的定义更改如下:

    public List<T> GetEntities<T>(string partitionKey, T entity) where T : TableEntity, new ()
    

    【讨论】:

      【解决方案2】:

      我为表存储编写了一个小型通用存储库:

       public class CloudTableRepository<T> where T : ITableEntity,new ()
      {
          private readonly string _tableName;
          private CloudTable _table;
      
          public CloudTableRepository(string tableName)
          {
              _tableName = tableName;
              InitializeTable();
          }
      
          #region Public Methods
      
          public virtual async Task<List<T>> GetPartitionAsync(string partitionKey, int takeCount = 1000)
          {
              var result = new List<T>();
              var query =
                  new TableQuery<T>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal,
                      partitionKey));
              query.TakeCount = takeCount;
              TableContinuationToken tableContinuationToken = null;
              do
              {
                  var queryResponse = await _table.ExecuteQuerySegmentedAsync(query, tableContinuationToken);
                  tableContinuationToken = queryResponse.ContinuationToken;
                  result.AddRange(queryResponse.Results);
              } while (tableContinuationToken != null);
              return result;
          }
      
          public virtual async Task<TableResult> GetSingleAsync(string partitionKey, string rowKey)
          {
             return  await GetSingle(partitionKey, rowKey);
          }
      
          public virtual async Task<T> UpdateAsync(T tableEntityData)
          {
              var updateCallistConfig = await GetSingleAsync(tableEntityData.PartitionKey, tableEntityData.RowKey);
              if (updateCallistConfig != null)
              {
                  var updateOperation = TableOperation.InsertOrMerge(tableEntityData);
                  var tableResult = await _table.ExecuteAsync(updateOperation);
                  return (T) tableResult.Result;
              }
              return default(T);
          }
      
          public virtual async Task<T> AddAsync(T tableEntityData)
          {
              var retrieveOperation = TableOperation.Insert(tableEntityData);
              var tableResult = await _table.ExecuteAsync(retrieveOperation);
              return (T) tableResult.Result;
          }
      
      
          #endregion
      
          #region Private Methods
      
          private async void InitializeTable()
          {
              var storageAccount =
                  CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("TableStorageConnectionString"));
              var tableClient = storageAccount.CreateCloudTableClient();
              _table = tableClient.GetTableReference(_tableName);
              await _table.CreateIfNotExistsAsync();
          }
      
          private async Task<TableResult> GetSingle(string partitionKey, string rowKey)
          {
              var retrieveOperation = TableOperation.Retrieve<T>(partitionKey, rowKey);
              var tableResult = await _table.ExecuteAsync(retrieveOperation);
              return tableResult; //(T) tableResult.Result;
          }
      
          #endregion
      }
      

      【讨论】:

        【解决方案3】:

        除了@serdar-ozler-microsoft 回答之外,您甚至不需要转换和转换实体即可返回。

        CloudTable.ExecuteQuery 方法有一个接受泛型类型的重载:

        public IEnumerable<TElement> ExecuteQuery<TElement>(
        TableQuery<TElement> query,
        TableRequestOptions requestOptions = null,
        OperationContext operationContext = null)
        where TElement : new(), ITableEntity
        

        您还可以使用 Linq 对表服务进行过滤。

        这样你就可以像这样重写你的方法:

        public List<T> GetEntities<T>(string partitionKey, T entity) where T : ITableEntity, new()
        {
            try
            {
                var tableClient = _account.CreateCloudTableClient();
                var table = tableClient.GetTableReference(entity.GetType().Name.ToLower());
                return table.CreateQuery<T>().Where(e => e.PartitionKey == partitionKey).ToList();
            }
            catch (StorageException ex)
            {
                //TODO: Add more trace info
                Trace.TraceInformation("Unable to retrieve entity based on query specs");
                return null;
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2014-12-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-11-29
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多