2010-09-20 35 views
1

我需要在Azure表的单个分区内选择多行以供以后更新。由于它们都具有相同的PartitionKey,我如何构建查询以选择多个RowKeys?如何使用StorageClient从Azure Table中选择50到100行?

我对原始(线上)查询应该看起来像什么感兴趣,如果可能的话还有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条件的数量,而不是语法...但我可以试试任何东西。

谢谢!

回答

2

这与我们在Lokad.Cloud中所做的相似。我记得你可以用这种方式选择最多100行,没有任何问题。您可以检查source code for the details并重新使用整个开源项目或只是您喜欢的部分。

这里的句法生成的样子:

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

但是,请记住,此操作不会受到表存储进行优化,导致次优的性能(表存储不使用索引这个操作)。这是一个向微软报告的错误,预计会在短时间内得到修复。

1

您是否有任何有关此错误修复进度的更新。 Azure Table存储现在是否使用索引执行此类查询(在单个分区上具有OR操作的多个rowkey)?

相关问题