ОК, я думаю, что здесь происходит несколько вещей. Один, я думаю, есть логический недостаток. Не должны
Convert.ToInt64(s.RowKey.Substring(0, s.PartitionKey.IndexOf("_")))
быть
Convert.ToInt64(s.PartitionKey.Substring(0, s.PartitionKey.IndexOf("_")))
Во-вторых, вы должны быть очень осторожны в отношении того, какие функции поддерживаются запросами таблиц Azure. Обычно это не так. Я протестировал .Substring()
и .IndexOf()
, и они не работают в запросах таблиц Azure, поэтому шансы на работу .ToInt64()
невелики.
Возможно, вы сможете переформатировать это, чтобы оно было
s => s.PartitionKey > startTicks.ToString() + "_"
&& s.PartitionKey < endTicks.ToString() + "_"
&& s.RowKey == "story_" + searchGuid
Скорее всего, это не будет генерировать очень эффективный запрос, поскольку Azure может запутаться, если у вас есть два фильтра на основе ключа раздела и просто выполняется сканирование таблицы. Другой вариант - не включать часть запроса endTicks, и когда вы обрабатываете результаты, когда вы получаете один из них, ключ раздела больше, чем конечные тики, останавливает обработку результатов.
Кроме того, ваш код в том виде, в котором он написан, не получит все элементы на основе токена продолжения, он просто получит первый набор результатов, которые будут возвращены. Я думаю, что ваш окончательный код должен выглядеть примерно так (не скомпилировано, не проверено, и я уверен, что люди могут увидеть некоторые улучшения производительности:
private class ListRowsContinuationToken
{
public string NextPartitionKey { get; set; }
public string NextRowKey { get; set; }
}
public Stories SelectStory(DateTime start, DateTime end, string searchGuid)
{
long startTicks = DateTime.MaxValue.Ticks - start.ToUniversalTime().Ticks;
long endTicks = DateTime.MaxValue.Ticks - end.ToUniversalTime().Ticks;
var stories = _ServiceContext.CreateQuery<Story>("Story").Where(s => s.PartitionKey > startTicks.ToString() + "_"
&& s.PartitionKey < endTicks.ToString() + "_"
&& s.RowKey == "story_" + searchGuid).Take(50);
var query = stories as DataServiceQuery<Story>;
Stories finalList = new Stories();
var results = query.Execute();
ListRowsContinuationToken continuationToken = null;
bool reachedEnd = false;
do
{
if ((continuationToken != null))
{
servicesQuery = servicesQuery.AddQueryOption("NextPartitionKey", continuationToken.NextPartitionKey);
if (!string.IsNullOrEmpty(continuationToken.NextRowKey))
{
servicesQuery.AddQueryOption("NextRowKey", continuationToken.NextRowKey);
}
}
var response = (QueryOperationResponse<T>)query.Execute();
foreach (Story result in response)
{
if (result.PartitionKey < endTicks.ToString())
{
finalList.AddRange(result);
}
else
{
reachedEnd = true;
}
}
if (response.Headers.ContainsKey("x-ms-continuation-NextPartitionKey"))
{
continuationToken = new ListRowsContinuationToken
{
NextPartitionKey = response.Headers["x-ms-continuation-NextPartitionKey"]
};
if (response.Headers.ContainsKey("x-ms-continuation-NextRowKey"))
{
continuationToken.NextRowKey = response.Headers["x-ms-continuation-NextRowKey"];
}
}
else
{
continuationToken = null;
}
} while (continuationToken != null && reachedEnd == false);
return finalList;
}