Frage

Ich brauche mehrere Zeilen innerhalb einer einzigen Partition von Azure Tabellen zur späteren Aktualisierung auszuwählen. Da sie alle die gleiche PartitionKey haben, wie strukturiere ich meine Abfrage mehrere RowKeys wählen?

Ich bin daran interessiert, was die rohe (auf dem Draht) Abfrage aussehen soll, und wenn möglich, die Linq Abfrage als auch.

Ich habe versucht, dies auf eigene Faust und mit dieser Abfrage gestartet:

 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;

Meine Frage sah wie folgt aus (von Fiedler)

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

und hier ist mein Fehler:

"<?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>"

ich denke, es kann mehr mit der Menge der RowKey Bedingungen Ich habe, anstatt die Syntax zu tun ... aber ich bin offen, alles zu versuchen.

Danke!

War es hilfreich?

Lösung

Das ist, etwas Ähnliches, was wir haben in getan Lokad.Cloud . Soweit ich mich erinnere Sie zu 100 Zeilen auf diese Weise problemlos auswählen kann. Sie können die Quellcode für die Details und Wiederverwendung entweder das gesamte Open-Source-Projekt oder nur die Teile, die Sie mögen.

Hier ist, wie die Syntax Generation aussieht wie:

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;
    }
  }
}

Doch bitte beachten Sie, dass dieser Vorgang nicht durch die Tabellenspeicher optimiert werden, was zu einer suboptimalen Leistung (Tabellen-Speicher ist nicht indiziert für diesen Vorgang verwendet wird). Das ist ein Fehler, die Microsoft gemeldet wurde und wird voraussichtlich in Kürze einige Zeit festgelegt werden.

Andere Tipps

Sie haben keine Update über die Fortschritte bei diesem Bug-Fix. Ist jetzt Azure Table Speicher diese Art der Abfrage (mehrere RowKey mit OR-Operation auf einzelne Partition) Durchführen Verwendung von Indizes?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top