كيف يمكنني اختيار 50 إلى 100 صف من جدول Azure باستخدام StorageClient؟

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

سؤال

أحتاج إلى تحديد عدة صفوف داخل قسم واحد من جداول Azure للتحديث اللاحق. نظرًا لأنهم جميعًا لديهم نفس PartitionKey ، كيف يمكنني بنية استعلامي لتحديد RowKeys متعددة؟

أنا مهتم بما يجب أن يبدو عليه استعلام RAW (على السلك) ، وإذا أمكن استفسار 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;

بدا استعلامي هكذا (من Fiddler)

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 التي لدي ، بدلاً من بناء الجملة ... لكنني منفتح لتجربة أي شيء.

شكرًا!

هل كانت مفيدة؟

المحلول

هذا شيء مشابه لما نقوم به Lokad.Cloud. كما أتذكر أنه يمكنك اختيار ما يصل إلى 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 الآن بإجراء هذا النوع من الاستعلام (RowKey متعدد أو التشغيل على قسم واحد) باستخدام الفهارس؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top