2012-11-19 35 views
5

我想用一個簡單的TableQuery從我的Azure Table中取回頂部n行。但通過下面的代碼,無論我對Take的限制如何,所有行都會被提取。爲什麼我的TakeLimit不符合TableQuery?

我在做什麼錯?

int entryLimit = 5; 

var table = GetFromHelperFunc(); 

TableQuery<MyEntity> query = new TableQuery<MyEntity>() 
    .Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "MyPK")) 
    .Take(entryLimit); 

List<FeedEntry> entryList = new List<FeedEntry>(); 
TableQuerySegment<FeedEntry> currentSegment = null; 

while (currentSegment == null || currentSegment.ContinuationToken != null) 
{ 
    currentSegment = table.ExecuteQuerySegmented(query, this.EntryResolver, currentSegment != null ? currentSegment.ContinuationToken : null); 
    entryList.AddRange(currentSegment.Results); 
} 


Trace.WriteLine(entryList.Count) // <-- Why does this exceed my limit? 
+1

接受的答案是不正確的 - 請參閱@ Fabrzio的答案。 – Ryan

回答

12

存儲SDK上的Take方法不像在LINQ中那樣工作。想象一下,你做這樣的事情:

TableQuery<TableEntity> query = new TableQuery<TableEntity>() 
       .Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "temp")) 
       .Take(5); 
var result = table.ExecuteQuery(query); 

當你開始遍歷result你最初只得到5個項目。但在下面,如果您繼續迭代result,則SDK將繼續查詢該表(並繼續查看5個項目的下一個「頁面」)。

如果我有我的表5000項,這個代碼將輸出所有5000項(和下面的SDK將做1000個請求,並獲取每個請求的5項):

TableQuery<TableEntity> query = new TableQuery<TableEntity>() 
       .Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "temp")) 
       .Take(5); 
var result = table.ExecuteQuery(query); 
foreach (var item in result) 
{ 
    Trace.WriteLine(item.RowKey); 
} 

將下面的代碼究竟取5個項目在1個請求,並停在那裏:

TableQuery<TableEntity> query = new TableQuery<TableEntity>() 
       .Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "temp")) 
       .Take(5); 
var result = table.ExecuteQuery(query); 
int index = 0; 
foreach (var item in result) 
{ 
    Console.WriteLine(item.RowKey); 
    index++; 
    if (index == 5) 
     break; 
} 

實際上,採取()方法設置頁面大小或「走數」(上TableQuery TakeCount屬性)。但如果你只需要5條記錄,那麼它仍然取決於你停止迭代。

在你的榜樣,您應該修改while循環停止到達TakeCount(這可以通過調用採取設置)時:

while (entryList.Count < query.TakeCount && (currentSegment == null || currentSegment.ContinuationToken != null)) 
{ 
    currentSegment = table.ExecuteQuerySegmented(query, currentSegment != null ? currentSegment.ContinuationToken : null); 
    entryList.AddRange(currentSegment.Results); 
} 
+0

非常感謝您的好評! –

+4

桑德里諾,你確定答案嗎?在我的測試中正確地工作。也許你正在引用一箇舊的和bug的版本的StorageClient https://github.com/WindowsAzure/azure-sdk-for-net/issues/144 –

+0

Nuget 9.1.0仍然有問題,並不得不按照這裏的建議。 –

相關問題