我正在试图通过partitionKey抽象来自Table的所有实体,如下所示:
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没有无参数构造函数。
答案 0 :(得分:21)
正如您在问题中提到的,T必须具有无参数构造函数。因此,请按如下方式更改方法的定义:
public List<T> GetEntities<T>(string partitionKey, T entity) where T : TableEntity, new ()
答案 1 :(得分:7)
我为表存储编写了一个小的通用存储库:
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
}
答案 2 :(得分:2)
除了@ 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;
}
}