2012-11-20 36 views
10
過濾

我試圖抽象的partitionKey歌廳所有實體從表中,像這樣:TableQuery <T>從Azure的TableStorage上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沒有無參數的構造函數。

回答

16

正如你在你的問題中提到的那樣,T必須有一個無參數的構造函數。因此,請改變你的方法的定義如下:

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

幹得好。謝謝@Serdar。完美的作品。 –

2

除了@塞爾達爾 - ozler微軟的答案,你甚至都不需要轉換和投實體返回。

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; 
    } 
} 
4

我寫了表存儲一個小的通用存儲庫:

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 
}