带有 table 存储的 Azure 函数 - 更新实体不工作
Azure function with table Storage - update entity not working
我有这个代码:
#r "Newtonsoft.Json"
#r "Microsoft.WindowsAzure.Storage"
using System;
using System.IO;
using System.Net.Http;
using Newtonsoft.Json;
using Microsoft.WindowsAzure.Storage.Table;
public async static void Run(string myIoTHubMessage, ICollector<SensorData> tableOutput, CloudTable activityTable,ICollector<SensorData> activityValue, ILogger log)
{
var data = JsonConvert.DeserializeObject<IoTMessage>(myIoTHubMessage);
string temp = data.param2;
double temperature = double.Parse(temp) * 0.01;
var sensor = new SensorData { Temperature = temperature.ToString(),DeviceId = data.deviceId, RowKey = data.messageId, PartitionKey = data.deviceId };
tableOutput.Add(sensor);
var query = new TableQuery<SensorValue>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, data.deviceId.ToString()));
var segment = await activityTable.ExecuteQuerySegmentedAsync(query, null);
if (segment.Results.Count == 0)
{
activityValue.Add(sensor);
}
else
{
SensorValue sensorValue = new SensorValue
{
PartitionKey = data.deviceId,
RowKey = data.messageId,
Temperature = Convert.ToInt16(temperature),
};
var operation = TableOperation.Replace(sensorValue);
await activityTable.ExecuteAsync(operation);
log.LogInformation(segment.Results.Count.ToString());
}
}
public class SensorData
{
public string RowKey { get; set; }
public string PartitionKey { get; set; }
public string Temperature { get; set; }
public string DeviceId {get; set;}
}
public class IoTMessage
{
public string messageId { get; set; }
public string temperature { get; set; }
public string deviceId { get; set; }
}
public class SensorValue : TableEntity
{
public string RowKey { get; set; }
public string PartitionKey { get; set; }
public string Temperature { get; set; }
public string DeviceId { get; set; }
}
该函数的工作方式是从传感器获取数据并将其保存到基地,但我想再做一个 table,其中只有给定设备的最后一个请求是保存。我检查 table 中是否有一个设备没有添加这样的 id,并且它可以正常工作。不幸的是,我在更新给定记录时遇到问题。在我看来是这样的:
if (segment.Results.Count == 0)
{
activityValue.Add(sensor);
}
else
{
SensorValue sensorValue = new SensorValue
{
PartitionKey = data.deviceId,
RowKey = data.messageId,
Temperature = Convert.ToInt16(temperature),
};
var operation = TableOperation.Replace(sensorValue);
await activityTable.ExecuteAsync(operation);
log.LogInformation(segment.Results.Count.ToString());
}
在 activityTable 中没有这样的设备的情况下记录自己 table 工作没有任何问题,不幸的是在有这样的设备的情况下更新不起作用,即没有错误,但也没有记录更新:(
在我的例子中,在 activityTable 中,PartitionKey 到 deviceId table 在请求中发送。我试着从早上 8 点开始,但没有任何效果,我无法处理它:(
快速解决方案:将 ETag
字段设置为 *
,如您在 Azure 提示与技巧文章 Updating an item from a Azure Storage Table 中所见。
稍长的版本:根据 Table 存储,您尝试替换的实体不存在,因为您省略了 ETag
值。
An ETag property is used for optimistic concurrency during updates. It is not a timestamp as there is another property called TimeStamp that stores the last time a record was updated. For example, if you load an entity and want to update it, the ETag must match what is currently stored. This is important b/c if you have multiple users editing the same item, you don't want them overwriting each other's changes.
将ETag设置为*
实际上是将其设置为接受任何值的通配符。
我有这个代码:
#r "Newtonsoft.Json"
#r "Microsoft.WindowsAzure.Storage"
using System;
using System.IO;
using System.Net.Http;
using Newtonsoft.Json;
using Microsoft.WindowsAzure.Storage.Table;
public async static void Run(string myIoTHubMessage, ICollector<SensorData> tableOutput, CloudTable activityTable,ICollector<SensorData> activityValue, ILogger log)
{
var data = JsonConvert.DeserializeObject<IoTMessage>(myIoTHubMessage);
string temp = data.param2;
double temperature = double.Parse(temp) * 0.01;
var sensor = new SensorData { Temperature = temperature.ToString(),DeviceId = data.deviceId, RowKey = data.messageId, PartitionKey = data.deviceId };
tableOutput.Add(sensor);
var query = new TableQuery<SensorValue>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, data.deviceId.ToString()));
var segment = await activityTable.ExecuteQuerySegmentedAsync(query, null);
if (segment.Results.Count == 0)
{
activityValue.Add(sensor);
}
else
{
SensorValue sensorValue = new SensorValue
{
PartitionKey = data.deviceId,
RowKey = data.messageId,
Temperature = Convert.ToInt16(temperature),
};
var operation = TableOperation.Replace(sensorValue);
await activityTable.ExecuteAsync(operation);
log.LogInformation(segment.Results.Count.ToString());
}
}
public class SensorData
{
public string RowKey { get; set; }
public string PartitionKey { get; set; }
public string Temperature { get; set; }
public string DeviceId {get; set;}
}
public class IoTMessage
{
public string messageId { get; set; }
public string temperature { get; set; }
public string deviceId { get; set; }
}
public class SensorValue : TableEntity
{
public string RowKey { get; set; }
public string PartitionKey { get; set; }
public string Temperature { get; set; }
public string DeviceId { get; set; }
}
该函数的工作方式是从传感器获取数据并将其保存到基地,但我想再做一个 table,其中只有给定设备的最后一个请求是保存。我检查 table 中是否有一个设备没有添加这样的 id,并且它可以正常工作。不幸的是,我在更新给定记录时遇到问题。在我看来是这样的:
if (segment.Results.Count == 0)
{
activityValue.Add(sensor);
}
else
{
SensorValue sensorValue = new SensorValue
{
PartitionKey = data.deviceId,
RowKey = data.messageId,
Temperature = Convert.ToInt16(temperature),
};
var operation = TableOperation.Replace(sensorValue);
await activityTable.ExecuteAsync(operation);
log.LogInformation(segment.Results.Count.ToString());
}
在 activityTable 中没有这样的设备的情况下记录自己 table 工作没有任何问题,不幸的是在有这样的设备的情况下更新不起作用,即没有错误,但也没有记录更新:(
在我的例子中,在 activityTable 中,PartitionKey 到 deviceId table 在请求中发送。我试着从早上 8 点开始,但没有任何效果,我无法处理它:(
快速解决方案:将 ETag
字段设置为 *
,如您在 Azure 提示与技巧文章 Updating an item from a Azure Storage Table 中所见。
稍长的版本:根据 Table 存储,您尝试替换的实体不存在,因为您省略了 ETag
值。
An ETag property is used for optimistic concurrency during updates. It is not a timestamp as there is another property called TimeStamp that stores the last time a record was updated. For example, if you load an entity and want to update it, the ETag must match what is currently stored. This is important b/c if you have multiple users editing the same item, you don't want them overwriting each other's changes.
将ETag设置为*
实际上是将其设置为接受任何值的通配符。