为什么我的TakeLimit由TableQuery兑现? [英] Why isn't my TakeLimit honored by TableQuery?

查看:196
本文介绍了为什么我的TakeLimit由TableQuery兑现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想取顶部的 N 的从我的Azure表行用一个简单的TableQuery。但与下面的code,所有行,而不管端来一我的极限在服用。

我在做什么错了?

  INT entryLimit = 5;变种表= GetFromHelperFunc();TableQuery<&myEntity所GT;查询=新TableQuery<&myEntity所GT;()
    。凡(TableQuery.GenerateFilterCondition(PartitionKey,QueryComparisons.EqualMyPK))
    。取(entryLimit);清单< FeedEntry> entryList =新的List< FeedEntry>();
TableQuerySegment< FeedEntry> currentSegment = NULL;而(currentSegment == NULL || currentSegment.ContinuationToken!= NULL)
{
    currentSegment = table.ExecuteQuerySegmented(!?查询,this.EntryResolver,currentSegment = NULL currentSegment.ContinuationToken:NULL);
    entryList.AddRange(currentSegment.Results);
}
Trace.WriteLine(entryList.Count)//< - 为什么这超出我的极限?


解决方案

在存储SDK取方法并不像它会在LINQ工作。想象一下,你做这样的事情:

  TableQuery< TableEntity>查询=新TableQuery< TableEntity>()
                。凡(TableQuery.GenerateFilterCondition(PartitionKey,QueryComparisons.Equal,TEMP))
                。取(5);
VAR的结果= table.ExecuteQuery(查询);

当你开始遍历结果您最初将只得到5个项目。但骨子里,如果你一直遍历结果,SDK将保留查询表(并继续以5个项目的下一个页面')

如果我在我的表5000项,这code将输出所有5000项(和SDK会做1000个请求,并获取每个请求的5项下):

  TableQuery< TableEntity>查询=新TableQuery< TableEntity>()
                。凡(TableQuery.GenerateFilterCondition(PartitionKey,QueryComparisons.Equal,TEMP))
                。取(5);
VAR的结果= table.ExecuteQuery(查询);
的foreach(在结果VAR项)
{
    Trace.WriteLine(item.RowKey);
}

以下code将获取1请求正好5个项目,并停在那里:

  TableQuery< TableEntity>查询=新TableQuery< TableEntity>()
                。凡(TableQuery.GenerateFilterCondition(PartitionKey,QueryComparisons.Equal,TEMP))
                。取(5);
VAR的结果= table.ExecuteQuery(查询);
INT索引= 0;
的foreach(在结果VAR项)
{
    Console.WriteLine(item.RowKey);
    指数++;
    如果(指数== 5)
        打破;
}

其实,在以()方式设置页面大小或走数(<一href=\"http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storage.table.tablequery.takecount.aspx\">TakeCount财产上TableQuery)。但它仍然是由你来停止迭代时间,如果你只想要5条记录。

在你的榜样,您应该修改while循环停止到达TakeCount(这可以通过调用采取设置)时:

 而(entryList.Count&LT; query.TakeCount&放大器;&安培;!(currentSegment == NULL || currentSegment.ContinuationToken = NULL))
{
    currentSegment = table.ExecuteQuerySegmented(查询,currentSegment = NULL currentSegment.ContinuationToken:!NULL);
    entryList.AddRange(currentSegment.Results);
}

I'd like to fetch top n rows from my Azure Table with a simple TableQuery. But with the code below, all rows are fetched regardless of my limit with the Take.

What am I doing wrong?

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?

解决方案

The Take method on the storage SDK doesn't work like it would in LINQ. Imagine you do something like this:

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

When you start iterating over result you'll initially get only 5 items. But underneath, if you keep iterating over the result, the SDK will keep querying the table (and proceed to the next 'page' of 5 items).

If I have 5000 items in my table, this code will output all 5000 items (and underneath the SDK will do 1000 requests and fetch 5 items per request):

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

The following code will fetch exactly 5 items in 1 request and stop there:

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

Actually, the Take() method sets the page size or the "take count" (TakeCount property on TableQuery). But it's still up to you to stop iterating on time if you only want 5 records.

In your example, you should modify the while loop to stop when reaching the TakeCount (which you set by calling Take):

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

这篇关于为什么我的TakeLimit由TableQuery兑现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆