如何在azure存储表中跨多个分区键进行查询



我有以下用例:

  • 用户请求创建一个小部件。创建一个新的记录,其细节在";请求";我的存储表中的分区
  • 当请求被满足时,原始请求被从";请求";分区并在";提供";分区

当涉及到查询小部件时,我需要搜索请求和提供的分区。从阅读文档中,我似乎可以创建过滤器?但这似乎是一个很大的开销,因为我知道我只会有一个记录返回(希望,除非我有一个bug(。但似乎我必须添加很多逻辑来处理分页。

到目前为止,这就是我要做的:

entity = tableClient.GetEntity<TableEntity>(
"requested",
requestId); 

类似的东西:

//entity = tableClient.GetEntity<TableEntity>(
//                    "requested",
//                    requestId); 
List<string> filters = new List<string>();
filters.Add($"PartitionKey eq '{"requested"}'");
filters.Add($"PartitionKey eq '{"provisioned"}'");
filters.Add($"RowKey eq '{requestId}'");
string filter = String.Join(" and ", filters);
//should only ever return one ... but ...
var entities =  tableClient.QueryAsync<TableEntity>(filter);
await foreach (Page<TableEntity> page in entities.AsPages())
{
Console.WriteLine("This is a new page!");
foreach (TableEntity qEntity in page.Values)
{
Console.WriteLine($"i found this request:  {qEntity.GetString("requestId")} with status: {"status"}");
}
}

这段代码目前不起作用,需要进行调试。但我想我应该检查一下是否有更简单的方法。

谢谢。

我建议首先编写一个TryGetEntityAsync扩展方法:

public static async Task<Response<T>?> TryGetEntityAsync<T>(this TableClient tableClient, string partitionKey, string rowKey, IEnumerable<string>? select = default, CancellationToken cancellationToken = default) where T : class, ITableEntity, new()
{
try
{
return await tableClient.GetEntityAsync<T>(partitionKey, rowKey, select, cancellationToken);
}
catch (RequestFailedException ex) when (ex.Status == 404)
{
return null;
}
}

然后,您可以一次一个地进行两点查询:

var entity =
(await tableClient.TryGetEntityAsync<TableEntity>("requested", requestId)) ??
(await tableClient.TryGetEntityAsync<TableEntity>("provisioned", requestId));

或同时:

var requestedEntityTask = tableClient.TryGetEntityAsync<TableEntity>("requested", requestId);
var provisionedEntityTask = tableClient.TryGetEntityAsync<TableEntity>("provisioned", requestId);
var entities = await Task.WhenAll(requestedEntityTask, provisionedEntityTask);
var entity = entities[0] ?? entities[1];

考虑到实体只存在于一个分区中,您可以将代码更改为以下内容:

List<string> filters = new List<string>();
filters.Add($"(PartitionKey eq 'requested' and RowKey eq '{requestId}')");
filters.Add($"(PartitionKey eq 'provisioned' and RowKey eq '{requestId}')");
string filter = String.Join(" or ", filters);
//should only ever return one ... but ...
var entities =  tableClient.QueryAsync<TableEntity>(filter);
await foreach (Page<TableEntity> page in entities.AsPages())
{
Console.WriteLine("This is a new page!");
foreach (TableEntity qEntity in page.Values)
{
Console.WriteLine($"i found this request:  {qEntity.GetString("requestId")} with status: {"status"}");
}
}

相关内容

  • 没有找到相关文章

最新更新