C# Azure表异步查询筛选器,带有';以';不提供顶级实体

C# Azure表异步查询筛选器,带有';以';不提供顶级实体,c#,azure,azure-table-storage,C#,Azure,Azure Table Storage,我希望在几千个实体中找到与我的TableQuery筛选器匹配的前100个实体(最近),我尝试了两种方法: 第一次尝试是在foreach循环中使用索引计数器,以在达到“100”时中断。这给了我一个奇怪的随机数据子集,其中大部分缺失,而不是100个实体;更像是几百而不是偶数 第二次尝试粘贴在下面,基本上忽略了我的延续标记,并将.take设置为“100”。这给出了与take整数匹配的实体的确切数量,但缺少了许多实体 每次尝试都会得到不同的结果,我想我知道为什么,但我不知道如何修复它以得到我需要的东西。

我希望在几千个实体中找到与我的TableQuery筛选器匹配的前100个实体(最近),我尝试了两种方法:

  • 第一次尝试是在
    foreach
    循环中使用索引计数器,以在达到“100”时中断。这给了我一个奇怪的随机数据子集,其中大部分缺失,而不是100个实体;更像是几百而不是偶数

  • 第二次尝试粘贴在下面,基本上忽略了我的延续标记,并将
    .take
    设置为“100”。这给出了与take整数匹配的实体的确切数量,但缺少了许多实体

  • 每次尝试都会得到不同的结果,我想我知道为什么,但我不知道如何修复它以得到我需要的东西。我意识到,出于性能原因,在时间戳上设置查询过滤器不是很好(它没有索引…对吧?)。那么,我是否应该用要过滤的日期/时间值填充另一个字段

            public async Task<List<ActivityModel>> GetActivitiesAsync(string DomainName, string NodeId, string ComputerName)
        {
            List<ActivityModel> activities = new List<ActivityModel>();
            CloudTable cloudTable = TableConnection("NodeEvents");
            string domainFilter = TableQuery.GenerateFilterCondition("DomainName", QueryComparisons.Equal, DomainName);
            string nodeIdFilter = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, NodeId);
            string computerNameFilter = TableQuery.GenerateFilterCondition("ComputerName", QueryComparisons.Equal, ComputerName);
            string filter1 = TableQuery.CombineFilters(domainFilter, TableOperators.And, nodeIdFilter);
            string filter2 = TableQuery.CombineFilters(filter1, TableOperators.And, computerNameFilter);
            TableContinuationToken continuationToken = null;
    
            var result = await cloudTable.ExecuteQuerySegmentedAsync(new TableQuery<ActivityModel>().Where(filter2).Take(100), continuationToken);
    
            if (result.Results != null)
            {
                foreach (ActivityModel entity in result.Results)
                {
                    activities.Add(entity);
                }
            }
    
            return activities;
        }
    
    public异步任务GetActivitiesAsync(字符串DomainName、字符串NodeId、字符串ComputerName)
    {
    列表活动=新列表();
    CloudTable CloudTable=TableConnection(“节点事件”);
    字符串domainFilter=TableQuery.GenerateFilterCondition(“DomainName”,QueryComparisons.Equal,DomainName);
    字符串nodeIdFilter=TableQuery.GenerateFilterCondition(“PartitionKey”,QueryComparisons.Equal,NodeId);
    字符串computerNameFilter=TableQuery.GenerateFilterCondition(“ComputerName”,QueryComparisons.Equal,ComputerName);
    string filter1=TableQuery.CombineFilters(domainFilter、TableOperators.And、nodeIdFilter);
    string filter2=TableQuery.CombineFilters(filter1,TableOperators.And,computerNameFilter);
    TableContinuationToken continuationToken=null;
    var result=await cloudTable.ExecuteQuerySegmentedAsync(new TableQuery().Where(filter2.Take)(100),continuationToken);
    if(result.Results!=null)
    {
    foreach(result.Results中的ActivityModel实体)
    {
    活动。添加(实体);
    }
    }
    返回活动;
    }
    
    您可以参考中的日志尾模式

    通过使用按相反日期和时间顺序排序的行键值检索最近添加到分区的n个实体

    背景和问题

    一个常见的要求是能够检索最近创建的实体,例如员工提交的十个最近的费用报销单。表查询支持使用$top查询操作返回集合中的前n个实体:没有等效的查询操作返回集合中的最后n个实体

    解决方案

    使用一个行键存储实体,该行键通过使用自然地按相反的日期/时间顺序排序,因此最近的条目始终是表中的第一个条目

    例如,为了能够检索员工最近提交的十份费用报销单,可以使用从当前日期/时间派生的反向勾号值。下面的C#代码示例显示了为从最近到最旧排序的行键创建合适的“倒勾”值的一种方法:

    您可以使用以下代码返回日期时间值:

    表查询如下所示:

    问题和注意事项

    在决定如何实现此模式时,请考虑以下几点:

    • 必须用前导零填充反向记号值,以确保 字符串值按预期排序

    • 您必须了解分区级别的可伸缩性目标。注意不要创建热点分区


    在这个示例中,Azure存储客户端库是否有一个等效的“top”?
    string invertedTicks = string.Format("{0:D19}", DateTime.MaxValue.Ticks - DateTime.UtcNow.Ticks);
    
    DateTime dt = new DateTime(DateTime.MaxValue.Ticks - Int64.Parse(invertedTicks));
    
    https://myaccount.table.core.windows.net/EmployeeExpense(PartitionKey='empid')?$top=10