Как выбрать от 50 до 100 строк из таблицы Azure с помощью StorageClient?

StackOverflow https://stackoverflow.com/questions/3748445

Вопрос

Мне нужно выбрать несколько строк в одном разделе таблиц Azure для последующего обновления.Поскольку все они имеют один и тот же PartitionKey, как мне структурировать запрос для выбора нескольких RowKeys?

Меня интересует, как должен выглядеть необработанный (по сети) запрос, а также, если возможно, запрос Linq.

Я попробовал это самостоятельно и начал с этого запроса:

 var results = from c in _ServiceContext.ForumThreadTable
                          where(
                          (
                          (c.RowKey == rk)    ||
                          (c.RowKey == "n1q") ||
                          (c.RowKey == "gm1w") ||
                          (c.RowKey == "fm1e") ||
                          (c.RowKey == "zbm1r") ||
                          (c.RowKey == "km1te1") ||
                          (c.RowKey == "jm1ye1") ||
                          (c.RowKey == "hm1u") ||
                          (c.RowKey == "gm1i") ||
                          (c.RowKey == "fm1te1") ||
                          (c.RowKey == "d4m1ye1") ||
                          (c.RowKey == "bm1u") ||
                          (c.RowKey == "bm1i") ||
                          (c.RowKey == "bm1o") ||
                          (c.RowKey == "bp1p") 
                          ) &&

                          c.PartitionKey == pk )
                          select c;

Мой запрос выглядел так (от скрипача)

GET http://127.0.0.1:10002/devstoreaccount1/ForumThreadTable()?$filter=(((((((((((((((RowKey%20eq%20'0634205427898279774')%20or%20(RowKey%20eq%20'n1q'))%20or%20(RowKey%20eq%20'gm1w'))%20or%20(RowKey%20eq%20'fm1e'))%20or%20(RowKey%20eq%20'zbm1r'))%20or%20(RowKey%20eq%20'km1te1'))%20or%20(RowKey%20eq%20'jm1ye1'))%20or%20(RowKey%20eq%20'hm1u'))%20or%20(RowKey%20eq%20'gm1i'))%20or%20(RowKey%20eq%20'fm1te1'))%20or%20(RowKey%20eq%20'd4m1ye1'))%20or%20(RowKey%20eq%20'bm1u'))%20or%20(RowKey%20eq%20'bm1i'))%20or%20(RowKey%20eq%20'bm1o'))%20or%20(RowKey%20eq%20'bp1p'))%20and%20(PartitionKey%20eq%20'GUIDeec4550c-a3fd-472b-9b7d-c79fae664415') HTTP/1.1
User-Agent: Microsoft ADO.NET Data Services
DataServiceVersion: 1.0;NetFx
MaxDataServiceVersion: 2.0;NetFx
x-ms-version: 2009-09-19
x-ms-date: Mon, 20 Sep 2010 02:49:48 GMT
Authorization: SharedKeyLite devstoreaccount1:MINFtQhWqbnYhn1spDGTGvPmNmW24YNzOeqBBtOletU=
Accept: application/atom+xml,application/xml
Accept-Charset: UTF-8
Host: 127.0.0.1:10002

и вот моя ошибка:

"<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>
 <error xmlns=\"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata\">
 <code>InvalidInput</code>
 <message xml:lang=\"en-US\">One of the request inputs is not valid.</message>
 </error>"

Я думаю, что это может быть больше связано с количеством имеющихся у меня условий RowKey, а не с синтаксисом...но я готов попробовать что угодно.

Спасибо!

Это было полезно?

Решение

Это что-то похожее на то, что мы делали в Локад.Облако.Насколько я помню, таким образом можно без проблем выбрать до 100 строк.Вы можете проверить исходный код для подробностей и повторно используйте либо весь проект с открытым исходным кодом, либо только те его части, которые вам нравятся.

Вот как выглядит генерация синтаксиса:

public IEnumerable<CloudEntity<T>> Get<T>(string tableName, string partitionKey, IEnumerable<string> rowKeys)
{
  Enforce.That(() => tableName);
  Enforce.That(() => partitionKey);
  Enforce.That(!partitionKey.Contains("'"), "Incorrect char in partitionKey.");

  var context = _tableStorage.GetDataServiceContext();

  foreach (var slice in rowKeys.Slice(MaxEntityTransactionCount))
  {
    // work-around the limitation of ADO.NET that does not provide a native way
    // of query a set of specified entities directly.
    var builder = new StringBuilder();
    builder.Append(string.Format("(PartitionKey eq '{0}') and (", HttpUtility.UrlEncode(partitionKey)));
    for (int i = 0; i < slice.Length; i++)
    {
      // in order to avoid SQL-injection-like problems 
      Enforce.That(!slice[i].Contains("'"), "Incorrect char in rowKey.");

      builder.Append(string.Format("(RowKey eq '{0}')", HttpUtility.UrlEncode(slice[i])));
      if (i < slice.Length - 1)
      {
        builder.Append(" or ");
      }
    }
    builder.Append(")");

    foreach(var entity in GetInternal<T>(context, tableName, builder.ToString()))
    {
      yield return entity;
    }
  }
}

Однако имейте в виду, что эта операция не будет оптимизирована хранилищем таблиц, что приведет к неоптимальной производительности (хранилище таблиц не использует индексы для этой операции).Об этой ошибке сообщили в Microsoft, и ожидается, что она будет исправлена ​​в ближайшее время.

Другие советы

У вас есть какие-либо обновления о прогрессе с помощью этого исправления ошибки. Является ли Azure Statile Storage, который выполняет этот тип запроса (множественный строк или операция на одном раздевании) с использованием индексов?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top