【发布时间】:2021-02-12 19:26:54
【问题描述】:
我正在将应用程序从 Cosmos C# SDK v2 迁移到 v3。我遇到了分页障碍,似乎无法弄清楚。
我有一个请求,它将搜索特定容器并通过请求进行分页。我的代码设置为处理页面大小(maxItemCount)和延续令牌。此外,前几个请求效果很好。但是当我喜欢第四页时,我在 Cosmos 的响应中得到的继续令牌是无效的。它看起来像这样:
[{\"range\":{\"min\":\"05C1DFFFFFFFFC\",\"max\":\"FF\"}}]
并且,当我将它传递给下一个请求以获取以下页面时,我收到以下错误:
Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: ; Reason: (Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: ; Reason: (Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: ; Reason: (Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: ; Reason: (Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: ; Reason: (Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: ; Reason: (Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: ; Reason: (Response status code does not indicate success: BadRequest (400); Substatus: 0; ActivityId: ; Reason: (CompositeContinuationToken is missing field: 'token': {"range":{"min":"05C1DFFFFFFFFC","max":"FF"}}););););););););
现在,我发现如果我在发送之前修改延续令牌,我可以获得请求成功。这需要我在 JSON 字符串中添加一个属性,您猜对了,token。
以下是处理此请求的相关代码:
IQueryable<LeadEntity> query;
var queryResults = new List<LeadEntity>();
var requestOptions = new QueryRequestOptions
{
MaxItemCount = input.Page?.Size ?? Core.Shared.Constants.PageSize.Default
};
if (input.Page?.ContinuationToken == "" || input.Page?.ContinuationToken == null)
{
query = Container.GetItemLinqQueryable<LeadEntity>(false, null, requestOptions);
}
else
{
query = Container.GetItemLinqQueryable<LeadEntity>(false, input.Page.ContinuationToken, requestOptions);
}
if (input.Criteria?.CallKeys.IsActive ?? false)
{
var callKeys = (input.Criteria.CallKeys?.Value ?? Enumerable.Empty<Guid>())
.Select(a => a.ToString());
query = query.Where(entity => callKeys.Contains(entity.CallKey));
}
if (input.Criteria?.AdvisorOids.IsActive ?? false)
{
var advisorOids = (input.Criteria.AdvisorOids?.Value ?? Enumerable.Empty<Guid>())
.Select(a => a.ToString());
query = query.Where(entity => advisorOids.Contains(entity.AdvisorOid));
}
if (input.Criteria?.CreatedOn.IsActive ?? false)
{
var start = input.Criteria.CreatedOn.Value.Start;
var duration = input.Criteria.CreatedOn.Value.Duration;
var end = input.Criteria.CreatedOn.Value.End;
if (start.HasValue && end.HasValue)
{
query = query.Where(entity => start.Value <= entity.Created.On && entity.Created.On <= end.Value);
}
else if (start.HasValue)
{
query = query.Where(entity => start.Value <= entity.Created.On && entity.Created.On <= start.Value.Add(+duration));
}
else if (end.HasValue)
{
query = query.Where(entity => end.Value >= entity.Created.On && entity.Created.On >= end.Value.Add(-duration));
}
else
{
query = query.Where(entity => false);
}
}
if (input.Criteria?.HasPortalKey.IsActive ?? false)
{
query = query.Where(entity => input.Criteria.HasPortalKey.Value
&& entity.PortalKey != null
&& entity.PortalKey != default(Guid).ToString()
);
}
query = query.Where(a => a.IsRemoved.IsDefined() ? !a.IsRemoved : true);
var totalCount = await query.CountAsync(ct);
query = input.Orderings?.Any() ?? false
? query.OrderBy(string.Join(",", input.Orderings))
: query;
query = input.Limit.HasValue
? query.Take(input.Limit.Value)
: query;
var feedIterator = query.ToFeedIterator();
FeedResponse<LeadEntity> feedResults = await feedIterator.ReadNextAsync(ct);
queryResults.AddRange(feedResults);
Console.WriteLine($"[LeadSearchAsync] total operation cost: {feedResults.RequestCharge} RUs");
var output = new PageOutput<LeadOutput>
{
Items = Mapper.Map<IEnumerable<LeadOutput>>(queryResults),
ContinuationToken = feedResults.ContinuationToken,
TotalCount = totalCount
};
return output;
我一直在谷歌上搜索,只发现发生这种情况的几个实例,它通常在 v2 sdk 上,而不是 v3。我的一部分想认为我做错了分页,但它似乎在大多数情况下都有效。
任何解决此问题的帮助将不胜感激。我没有在 v3 SDK 上找到很多关于分页的文档,它与 v2 明显不同。
【问题讨论】:
标签: c# pagination azure-cosmosdb azure-cosmosdb-sqlapi