棘手的部分RowKey
是string
,其价值类似于Mon Nov 14 12:26:42 2016
我尝试使用Timestamp
之类的查询
var lowerlimit = DateTime.UtcNow; // its should be nearer to table timestamp data.
TableQuery<TemperatureEntity> query2 = new TableQuery<TemperatureEntity>().Where(TableQuery.GenerateFilterConditionForDate("Timestamp", QueryComparisons.GreaterThanOrEqual,lowerlimit));
var test = table.ExecuteQuery(query2);
MyEntity.cs
public class MyEntity : TableEntity
{
public MyEntity(string partitionKey, string rowKey)
{
this.PartitionKey = partitionKey;
this.RowKey = rowKey;
}
public MyEntity() { }
public Int64 DevideId { get; set; }
public string RowKey { get; set; }
}
//下面的查询提供了完整的数据 的 Program.cs的
// Retrieve the storage account from the connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
CloudConfigurationManager.GetSetting("StorageConnectionString"));
// Create the table client.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
// Create the CloudTable object that represents the "TemperatureData" table.
CloudTable table = tableClient.GetTableReference("TemperatureData");
// retrive data
TableQuery<TemperatureEntity> query = new TableQuery<TemperatureEntity>();
var data = table.ExecuteQuery(query);
答案 0 :(得分:19)
新,
如果您需要在分区中拥有最新条目,则使用行键的字符串日期时间不是一个好方法,因为表存储基于行键按升序存储实体。
如果您在当前点可以更改行键的值,请使用DateTime.UtcNow.Ticks
:
var invertedTimeKey = DateTime.MaxValue.Ticks - DateTime.UtcNow.Ticks
通过这种方法,在查询表格时,您可以输入与最新表格相对应的1个条目。
如果您无法更改行键的值,则必须检索分区中的所有条目,这意味着将所有条目加载到内存中,然后使用时间戳对它们进行排序以检索最后一个条目。如果您有很多条目,这绝对不是一个好方法。
var lastResult = results.OrderByDescending(r => r.Timestamp).FirstOrDefault();
答案 1 :(得分:7)
Azure表服务不支持Order By
功能,因此当前设置的唯一选项是下载所有实体并在客户端进行chrnological反向排序。当表中的实体数量变大时,这显然不是最佳解决方案。
其他选项(需要您重新设计应用程序)将以反向刻度转换日期/时间值:
var rowKey = (DateTime.MaxValue.Ticks - DateTimeValueForRowKey.Ticks).ToString("d19")
这将确保将最新条目添加到表格的顶部而不是表格的底部。要获取最新条目,您只需从表中获取第一个实体。
答案 2 :(得分:1)
在某些情况下 可能有效的另一种方法是通过生成范围查询或一组范围“智能强力”表。查询,以获取您希望使用的值,并一次将其清除。
在这种情况下,由于行键的格式为Mon Nov 14 12:26:42 2016
(并且假设OP @neo不能更改它),并且他们想要最新的结果,那么您可以得到很好的结果前缀查询(仍然是字典范围查询)which Azure says is the fastest type of non-exact query的性能:
第二个最佳选择是使用
PartitionKey
并对RowKey
值范围进行过滤以返回多个实体的范围查询。PartitionKey
值标识特定分区,而RowKey
值标识该分区中实体的子集。例如:$filter=PartitionKey eq 'Sales' and RowKey ge 'S' and RowKey lt 'T'
。
完成这项工作的一个巧妙技巧是利用Mon Nov 14
仅是以下日期的事实:
1977-11-14
1983-11-14
1988-11-14
1994-11-14
2005-11-14
2011-11-14
2016-11-14
2022-11-14
2033-11-14
2039-11-14
2044-11-14
etc
因此,只需对Mon Nov 14
进行前缀搜索,就可以安全地返回隐含所需年份(2016年)的记录,还可以返回其他1或2年的记录,这些记录可以安全地排除在内存中而不会显着降低性能(例如2011和2022)。
请注意,如果您为PartitionKey
提供了一个确切的值(在这种情况下始终为"raspberrypi"
),Azure仅使用实数范围查询。 OP的原始查询没有。
String partitionKeyFilter = TableQuery.GenerateFilterCondition(
propertyName: "PartitionKey",
operation : QueryComparisons.Equal,
givenValue : "raspberrypi"
);
DateTime today = DateTime.UtcNow;
String todayPrefix = today.ToString( "ddd MMM dd", CultureInfo.InvariantCulture );
String rowKeyFilter = TableQuery.GenerateFilterCondition(
propertyName: "RowKey",
operation : QueryComparisons.GreaterThan,
givenValue : todayPrefix
);
TableQuery<TemperatureEntity> query = new TableQuery<TemperatureEntity>()
{
FilterString = TableQuery.CombineFilters( partitionKeyFilter, TableOperators.And, rowKeyFilter );
}
List<TemperatureEntity> queryResults = table
.ExecuteQuery( query )
.Where( e => e.RowKey.EndsWith( today.ToString(" yyyy") ) ) // Filter current-year in the client.
.ToList();