C# 如何在Azure表存储中使用行键或时间戳检索最新记录
棘手的部分是C# 如何在Azure表存储中使用行键或时间戳检索最新记录,c#,azure,azure-storage,C#,Azure,Azure Storage,棘手的部分是RowKey是string,它的值类似于Mon Nov 14 12:26:42 2016 我试着使用时间戳进行类似的查询 var lowerlimit = DateTime.UtcNow; // its should be nearer to table timestamp data. TableQuery<TemperatureEntity> query2 = new TableQuery<TemperatureEntity>().W
RowKey
是string
,它的值类似于Mon Nov 14 12:26:42 2016
我试着使用时间戳
进行类似的查询
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);
//下面的查询提供了完整的数据
Program.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; }
}
// 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);
//从连接字符串中检索存储帐户。
CloudStorageAccount-storageAccount=CloudStorageAccount.Parse(
GetSetting(“StorageConnectionString”);
//创建表客户端。
CloudTableClient tableClient=storageAccount.CreateCloudTableClient();
//创建表示“TemperatureData”表的CloudTable对象。
CloudTable=tableClient.GetTableReference(“TemperatureData”);
//检索数据
TableQuery=新建TableQuery();
var数据=table.ExecuteQuery(查询);
Azure Table Service不支持按
排序的功能,因此,使用当前的设置,您唯一的选择是下载所有实体,并在客户端按逆时针顺序对其排序。当表中的实体数量变大时,这显然不是最佳解决方案
其他选项(需要您重新设计应用程序)是将日期/时间值转换为反向刻度:
var rowKey = (DateTime.MaxValue.Ticks - DateTimeValueForRowKey.Ticks).ToString("d19")
这将确保将最新条目添加到表的顶部,而不是表的底部。要获取最新条目,您只需从表中获取第一个实体。Neo
如果您需要在分区中有最新的条目,那么为行键使用字符串日期时间不是一个好方法,因为表存储根据行键按升序存储实体
如果在当前点可以更改行键的值,请使用DateTime.UtcNow.Ticks
:
var invertedTimeKey = DateTime.MaxValue.Ticks - DateTime.UtcNow.Ticks
使用这种方法,在查询表时,您将能够获取与最新数据对应的1个条目
如果不能更改行键的值,则必须检索分区中的所有条目,这意味着将所有条目加载到内存中,然后使用时间戳对它们进行排序,以检索最后一个条目。如果你有很多条目,这绝对不是一个好方法
var lastResult = results.OrderByDescending(r => r.Timestamp).FirstOrDefault();
另一种在某些情况下可以很好地工作的方法是,通过为您希望工作的值生成一个范围查询或一组范围查询来“巧妙地强制”表,并一次将它们全部触发
在这种情况下,由于行键的格式为2016年11月14日星期一12:26:42(并且假设OP@neo无法更改),并且他们想要最新的结果,那么使用前缀查询(仍然是字典范围查询)可以获得良好的性能:
其次是范围查询,它使用PartitionKey
并对RowKey
值范围进行筛选,以返回多个实体。PartitionKey
值标识特定分区,而RowKey
值标识该分区中实体的子集。例如:$filter=PartitionKey eq'Sales'和RowKey ge'S'以及RowKey lt'T'
实现这一点的一个巧妙技巧是利用以下事实:11月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
因此,只需在11月14日星期一进行前缀搜索,就可以安全地返回隐含期望年份(2016年)的记录,也可以安全地在内存中排除其他1或2年的记录,而不会对性能造成重大影响(如2011年和2022年)
请注意,Azure仅在为分区键
提供准确值时才使用实际范围查询,在本例中,该值始终为“raspberrypi”
。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();
String partitionKeyFilter=TableQuery.GenerateFilterCondition(
propertyName:“PartitionKey”,
操作:QueryComparisons.Equal,
给定值:“树莓”
);
DateTime today=DateTime.UtcNow;
String todayPrefix=today.ToString(“ddd MMM dd”,CultureInfo.InvariantCulture);
字符串rowKeyFilter=TableQuery.GenerateFilterCondition(
propertyName:“行键”,
操作:QueryComparisons.GreaterThan,
givenValue:todayPrefix
);
TableQuery=新建TableQuery()
{
FilterString=TableQuery.CombineFilters(partitionKeyFilter、TableOperators.And、rowKeyFilter);
}
列表查询结果=表
.ExecuteQuery(查询)
.Where(e=>e.RowKey.EndsWith(today.ToString(“yyyy”))//在客户端中筛选当前年份。
.ToList();
请看下面Gaurav的回答,因为代码片段正确指定了ToString格式d19,其中零填充数字。RowKey存储为字符串,因此它被排序为字符串,这意味着“2”大于“1582”。这是指向MS文档的链接,描述了解决方案。感谢Vivien,她正在按功能查找订单,使用RowKey作为DateTime.UtcNow.Ticks将有助于提取最近24小时的数据?查询中的更改将起作用?行键的日期时间值是多少?它是表存储中的一个字段吗?这是存储在RowKey
字段中的值。但仅在语句var RowKey=(DateTime.MaxValue.Ticks-DateTimeValueForRowKey.Ticks)之后。ToString(“d19”)
。执行时,我们可以在RowKey处获取值。在上面的陈述之前,我们如何获得rowkey的DateTimeValueForRowKey
的值。我建议问一个新问题。请在此处包含所有详细信息。@GauravMantri Antoni要求您使用尚未存在的DateTimeValueForRowKey,因为该条目尚未创建。。。这是创建实体的代码