方案如下:当前的MVC5项目提供了几个视图,这些视图通过使用各种API调用来检索其数据。这些调用仅使用https://[some_url]
字符串进行,必要时替换变量。
所有调用都会返回JSON字符串,这些字符串将根据MVC模型转换为对象。我还要指出的是,这样的应用程序不包含任何数据库,因为它充当了一系列流程中的一个步骤,将创建的对象传递给下一个应用程序。
一个呼叫针对Azure Table Storage。该特定表包含数千个条目,并且正在稳定增长。使用“普通” API调用(例如https://api123.sample.net/application/[...]/
)仅返回前1,000个条目。
此SO post是我的起点,建议通过添加查询参数NextParitionKey
和NextRowKey
来修改URL。前面提到的SO帖子中的一条评论也指出了这一点Microsoft Doc,提出了向查询添加参数的相同方法。
由于我一直在使用的呼叫在标头中返回了x-ms-continuation-NextPartitionKey
和x-ms-continuation-NextRowKey
,所以我认为应该使用它们来修改查询网址。在Postman中输入参数化查询后,我能够修改URL并得到JSON结果。
但是,这是实际的问题,尽管使用了查询参数,但API调用的结果仅返回了1,000。比较参数化的url调用和之前使用的标准调用的结果,发现JSON文件确实不同。
我认为不能更改每个调用1,000个条目的限制,但是如果可能的话,我将如何使用基于url的api调用从该特定数据库中检索所有条目(请参见下面的方法)?我的意思是,如果使用该参数每次调用也仅返回1,000个条目,那么如何“链接”这些调用并找出最后一个数据库条目以终止整个过程。
我假设在这种情况下无法使用基于url的方法。是否需要将实际的API调用提取到适当的方法中(链接将不胜感激)?
作为补充信息,请考虑以下方法(注意:稍作修改):
public static string GetJsonDataFromApi()
{
var jsonData = "";
var apiKey = System.Configuration.ConfigurationManager.AppSettings["ApiKey"];
var url = BuildWebApiUrl();
if (IsNullOrWhiteSpace(url) && IsNullOrEmpty(url))
return jsonData;
var webClient = new WebClient
{
Encoding = Encoding.UTF8,
};
using (webClient)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
webClient.Headers.Add("subscription-key", apiKey);
try
{
jsonData = webClient.DownloadString(url);
}
catch (WebException e)
{
}
return !IsNullOrEmpty(jsonData) ? jsonData : "";
}
}
private static string BuildWebApiUrl()
{
var tableName = System.Configuration.ConfigurationManager.AppSettings["Table"];
[some more System.ConfigurationVariables]
return string.Format(urlTemplate, tableName, nextPartitionKey, nextRowKey);
}
关于此问题,我认为这是一种更好的方式来编写代码以查询Azure表中的所有实体。如果要查询Azure表中的所有实体,则可以使用SDk Microsoft.Azure.Cosmos.Table
来实现它。
var acc = new Microsoft.Azure.Cosmos.Table.CloudStorageAccount(
new StorageCredentials("account name", "account key"), true);
var tableClient = acc.CreateCloudTableClient();
var table = tableClient.GetTableReference("table name");
TableContinuationToken token = null;
var entities = new List<MyEntity>();
do
{
var queryResult = table.ExecuteQuerySegmented(new TableQuery<MyEntity>(), token);
entities.AddRange(queryResult.Results);
token = queryResult.ContinuationToken;
} while (token != null);