У меня есть вызов REST для извлечения всех данных из небольшого (145 строк) EasyTable, используемого для приложения на основе Azure.
При извлечении данных ответ указывает, что мне нужно найти страницу, чтобы собрать вседанные.Он возвращает данные порциями по 50 строк за раз.Приведенный ниже код собирает ответы до тех пор, пока больше не будет возвращено никаких данных.Когда я запускаю его, первый ответ дает мне 50 уникальных строк и содержит поле $top=950&$skip=50
для последующего вызова.Однако, когда я делаю этот вызов, он также возвращает 50 строк, но некоторые являются дубликатами первых 50 строк.Так продолжается до тех пор, пока я не получу 145 строк, но, поскольку некоторые из них являются дубликатами, я пропускаю некоторые строки и имею некоторые избыточные строки.
Данные в таблице постоянны во время всех вызовов, они меняются только каждыенесколько дней, и я подтвердил, что это не изменилось ни в одном из моих тестов.
Я знаю, что могу переформулировать и упростить код, но я не могу найти ничего, что должно вызывать мою проблему.Любые указатели, где искать?
Я попытался использовать $filter
и изменить $top=200
, но единственное, что работает, - это убедиться, что фильтр никогда не возвращает более 50 строк.К сожалению, поскольку данные могут измениться, для настройки последовательности вызовов для этого потребуется дополнительное поле для запроса.Я сделаю это в конце, если понадобится, но кажется, что подкачка должна работать.
private string AzureTablesStandardGet(string tableURL, string queryString)
{
GetAzuremysite();
CookieContainer cookieJar = new CookieContainer();
string uriQueryString = System.Uri.EscapeUriString(queryString);
string sURL = string.Format("https://mysite.azurewebsites.net/tables{0}?{1}", tableURL, uriQueryString);
WebRequest wrGETURL;
wrGETURL = WebRequest.Create(sURL);
wrGETURL.Proxy = WebRequest.GetSystemWebProxy();
wrGETURL.Proxy.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
wrGETURL.Headers.Add("ZUMO-API-VERSION", "2.0.0");
wrGETURL.Headers.Add("X-ZUMO-AUTH", mysite.access_token);
wrGETURL.ContentType = "application/json;odata=nometadata";
wrGETURL.Method = "GET";
((HttpWebRequest)wrGETURL).Date = DateTime.UtcNow;
((HttpWebRequest)wrGETURL).CookieContainer = cookieJar;
string sLine = "";
var mine = "first";
try
{
while (mine.Equals("first") || mine.ToLower().Contains("rel=next"))
{
var httpResponse = (HttpWebResponse)wrGETURL.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
string newLine = streamReader.ReadToEnd();
sLine += newLine;
}
mine = httpResponse.GetResponseHeader("Link");
if (mine.ToLower().Contains("rel=next"))
{
string newURL = mine.Split(';')[0];
newURL = newURL.Split('?')[1];
sURL = string.Format("{0}?{1}", sURL.Split('?')[0], newURL);
wrGETURL = WebRequest.Create(sURL);
((HttpWebRequest)wrGETURL).CookieContainer = cookieJar;
wrGETURL.Proxy = WebRequest.GetSystemWebProxy();
wrGETURL.Proxy.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
wrGETURL.Headers.Add("ZUMO-API-VERSION", "2.0.0");
wrGETURL.Headers.Add("X-ZUMO-AUTH", mysite.access_token);
wrGETURL.ContentType = "application/json;odata=nometadata";
((HttpWebRequest)wrGETURL).Date = DateTime.UtcNow;
wrGETURL.Method = "GET";
}
}
}
catch (WebException e)
{
Console.WriteLine(e.Message);
System.Threading.Thread.Sleep(1000);
}
sLine = sLine.Replace("][",",");
return sLine;
}
}
}
Так, например, первый вызов будет выглядеть примерно так:
https://mysite.azurewebsites.net/tables/mytable?$top=1000
и второй, основываясь на ответе в заголовке Link:
header = http://mysite.azurewebsites.net/?%24top=950&%24skip=50; rel=next
GET call = https://mysite.azurewebsites.net/tables/mytable?%24top=950&%24skip=50
Я попытался сделать первыйпозвоните
https://mysite.azurewebsites.net/tables/mytable?$top=1000&$skip=0
, но это не имеет значения
Обновление 2018-04-26 Изменение кода для индексации вручную через таблицу 50 элементов ввремя возвращает все данные без дубликатов.Теперь я действительно запутался.
Эта последовательность вызовов возвращает 145 элементов, но некоторые являются дубликатами, поэтому возвращаются не все данные.Обратите внимание, что, хотя я запрашиваю более 50 строк на запрос, сервер возвращает только 50 строк и заголовок Link , указывающий, что не все данные были возвращены, и он включает параметры, которые я должен использовать, чтобы получить остальную частьdata.
https://mysite.azurewebsites.net/tables/mytable?%24top=1000
https://mysite.azurewebsites.net/tables/mytable?%24top=950&%24skip=50
https://mysite.azurewebsites.net/tables/mytable?%24top=900&%24skip=100
Четвертый вызов не требуется, поскольку я использую Link rel = next not present, что означает прекращение запроса данных
Эта серия вызовов возвращает все данные без дубликатов
https://mysite.azurewebsites.net/tables/mytable?%24top=50&%24skip=0
https://mysite.azurewebsites.net/tables/mytable?%24top=50&%24skip=50
https://mysite.azurewebsites.net/tables/mytable?%24top=50&%24skip=100
Однако для этого требуется четвертый вызов, который возвращает пустой массив «[]», который я использую, чтобы указать, что я собрал всю информацию и могу остановиться.
https://mysite.azurewebsites.net/tables/mytable?%24top=50&%24skip=150
Поскольку $top=xx
означает, сколько всего элементов нужно вернуть, а не на страницу, вызовы должны возвращать одинаковые результаты, но это не так.