简体   繁体   English

从 Azure 表存储 OData 过滤查询中读取超过 1000 行?

[英]Read more than 1000 rows from Azure Table Storage OData filter query?

How do we read more than 1000 rows from Azure Table Storage?我们如何从 Azure 表存储中读取超过 1000 行? Here is the code I'm using for reading data from Table Storage and this only retrieves 1000 rows:这是我用于从表存储读取数据的代码,它只检索 1000 行:

readData()
{
    var s = @$"https://{storageAccountName}.table.core.windows.net/{tableName}()";          
    var baseurl = $"{s}<sas-token>&$filter=Name%20eq%20'XYZ'";
    var data = GetForOData(baseurl);
    var responseData = data.Data.Replace(".", "_");
    var odata = JsonConvert.DeserializeObject<ODataResponse>(responseData); 
}

GetForOData(string url) {return InvokeForOData<Object>("GET", url, null, null);}

private static HttpResponseData InvokeForOData<T>(string method, string url, Object id, T data)
{
    var Response = new HttpResponseData()
    {
         Code = HttpStatusCode.RequestTimeout, Data = string.Empty, Message = string.Empty
    };
            
    var PostParam = string.Empty;
    if (data != null) { PostParam = data.ToString(); }
    var postData = Encoding.UTF8.GetBytes(PostParam);
    var request = (HttpWebRequest)WebRequest.Create(new Uri(url + (id == null ? "" : '/' + id.ToString())));
     request.Method = method;
     // add headers
     if (postData.Length > 0)
     {
        using (Stream requestStream = request.GetRequestStream())
        { requestStream.Write(postData, 0, postData.Length); }
     }
     using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
     {
        Response.Code = response.StatusCode;
        using (var stream = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
        { Response.Data = stream.ReadToEnd(); }
     }            
     return Response;
}

Where do I check for x-ms-continuation-NextPartitionKey and x-ms-continuation-NextRowKey and use them in the next request?我在哪里检查 x-ms-continuation-NextPartitionKey 和 x-ms-continuation-NextRowKey 并在下一个请求中使用它们?

Update: I was able to find nextPartitionKey and nextRowKey header values.更新:我能够找到 nextPartitionKey 和 nextRowKey header 值。 How do I pass these values in the next request?如何在下一个请求中传递这些值?

                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    Response.Code = response.StatusCode;
                    var nextPartitionKey = response.Headers["x-ms-continuation-NextPartitionKey"];
                    var nextRowKey = response.Headers["x-ms-continuation-NextRowKey"];
                    using (StreamReader stream = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                    {
                        Response.Data = stream.ReadToEnd();
                    }
                }

A single call to Azure Table Storage will return a maximum of 1000 entities.对 Azure 表存储的单次调用将返回最多 1000 个实体。 If there are more entities matching a query, you will get a continuation token back and you will need to use that to get the next set of entities.如果有更多实体与查询匹配,您将获得一个延续令牌,您将需要使用它来获取下一组实体。

So in your case, in order to read more than 1000 entities you will have to send the request, get the data and check for continuation token in the response ( x-ms-continuation-NextPartitionKey and x-ms-continuation-NextRowKey ) and use them in the next request.因此,在您的情况下,为了读取 1000 多个实体,您必须发送请求、获取数据并检查响应中的延续令牌( x-ms-continuation-NextPartitionKeyx-ms-continuation-NextRowKey )和在下一个请求中使用它们。

You can learn more about pagination in Azure Table Storage here: https://docs.microsoft.com/en-us/rest/api/storageservices/query-timeout-and-pagination .您可以在此处了解有关 Azure 表存储中的分页的更多信息: https://docs.microsoft.com/en-us/rest/api/storageservices/query-timeout-and-pagination

UPDATE更新

Please see the code below (untested though):请看下面的代码(虽然未经测试):

private static HttpResponseData InvokeForOData<T>(string method, string url, Object id, T data)
{
  var Response = new HttpResponseData()
  {
        Code = HttpStatusCode.RequestTimeout, 
        Data = string.Empty, 
        Message = string.Empty,
        NextPartitionKey = string.Empty,
        NextRowKey = string.Empty
  };
            
  var PostParam = string.Empty;
  if (data != null) { PostParam = data.ToString(); }
  var postData = Encoding.UTF8.GetBytes(PostParam);
  var request = (HttpWebRequest)WebRequest.Create(new Uri(url + (id == null ? "" : '/' + id.ToString())));
    request.Method = method;
    // add headers
    if (postData.Length > 0)
    {
      using (Stream requestStream = request.GetRequestStream())
      { requestStream.Write(postData, 0, postData.Length); }
    }
  using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
  {
      Response.Code = response.StatusCode;
      var nextPartitionKey = response.Headers["x-ms-continuation-NextPartitionKey"];
      var nextRowKey = response.Headers["x-ms-continuation-NextRowKey"];
      using (StreamReader stream = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
      {
          Response.Data = stream.ReadToEnd();
          Response.NextPartitionKey = nextPartitionKey;
          Response.NextRowKey = nextRowKey;
      }
  }     
  return Response;
}

Basically what I have done is added two properties ( NextPartitionKey and NextRowKey ) in your HttpResponseData object and populate that with the nextPartitionKey and nextRowKey respectively you get from response header.基本上我所做的是在您的HttpResponseData object 中添加两个属性( NextPartitionKeyNextRowKey ),并分别使用从响应 header 中获得的nextPartitionKeynextRowKey填充它。

What you have to do in your code (where you're processing the response) is check if either of these two values are not null or empty.您必须在代码(处理响应的地方)中做的是检查这两个值中的任何一个是否不是 null 或为空。 A non null/empty value would indicate that more entities are present.非空/空值表示存在更多实体。

If that's the case, then what you have to do is modify the URL by appending NextPartitionKey and NextRowKey values as query string parameters (please see the link above for details) and send the request again.如果是这种情况,那么您需要做的是修改 URL,将NextPartitionKeyNextRowKey值附加为查询字符串参数(有关详细信息,请参阅上面的链接)并再次发送请求。 You will need to do this till the time you get both of these values as either null or empty strings.您将需要这样做,直到您将这两个值都作为 null 或空字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM