【问题标题】:Azure Function into Table StorageAzure 函数到表存储
【发布时间】:2017-03-21 10:51:30
【问题描述】:

我有一个 Azure 函数,我想让它从 EventHub 获取消息(这相当简单且有效),然后在运行时使用表绑定将该信息放入表存储中。

这是我目前所拥有的:

public static async Task Run(string eventHubMessage, TraceWriter log, Binder binder)
{
   var m = JsonConvert.DeserializeObject<Measurement>(eventHubMessage);
   var attributes = new Attribute[]
    {
        new StorageAccountAttribute("AzureWebJobsTest"),
        new TableAttribute(tableName, m.PartitionKey, m.RowKey)
    };

    using(var output = await binder.BindAsync<MyTableEntity>(attributes)) 
    {
        if(output == null)
           log.Info($"4. output is null");
        else
        {
            output.Minimum = m.Minimum;
            output.Maximum = m.Maximum;
            output.Average = m.Average;
            output.Timestamp = m.Timestamp;
            output.ETag = m.ETag;  

            output.WriteEntity(/* Need an operationContext*/)
        }
    }
}
public class MyTableEntity : TableEntity, IDisposable
{
    public double Average { get; set;}
    public double Minimum { get; set;}
    public double Maximum { get; set;}

    bool disposed = false;
    public void Dispose()
    { 
        Dispose(true);
        GC.SuppressFinalize(this);           
    }

   protected virtual void Dispose(bool disposing)
   {
      if (disposed)
         return; 

      if (disposing) 
      {
      }

      disposed = true;
   }
}

我的问题;

1) 输出总是为空。

2) 即使输出不为空,我也不知道 OperationContext 需要什么,或者调用 ITableEntity.Write() 是否是让它写入表存储的正确方法。

ETA Json 绑定:

{
  "bindings": [
    {
      "type": "eventHubTrigger",
      "name": "eventHubMessage",
      "direction": "in",
      "path": "measurements",
      "connection": "MeasurementsConnectionString"
    }
  ],
  "disabled": false
}

【问题讨论】:

  • @mikhail,我添加了 JSON。我想在运行时根据从集线器传入的表名进行绑定。我有很多表,我需要命令式绑定。

标签: c# azure azure-functions azure-table-storage


【解决方案1】:

要向表中添加新条目,您应该绑定到IAsyncCollector 而不是实体本身,然后创建一个新实体并调用AddAsync。以下 sn-p 对我有用:

var attributes = new Attribute[]
{
    new StorageAccountAttribute("..."),
    new TableAttribute("...")
};

var output = await binder.BindAsync<IAsyncCollector<MyTableEntity>>(attributes);     
await output.AddAsync(new MyTableEntity()
{
    PartitionKey = "...",
    RowKey = "...",
    Minimum = ...,
    ...
});

【讨论】:

  • 谢谢,它开始工作了。不过现在,每次函数完成时我都会得到这个。 Microsoft.Azure.WebJobs.Host: Error while handling parameter binder after function returned: Microsoft.WindowsAzure.Storage: The specified entity already exists. 这是因为我可能试图插入重复项吗?
  • 是的,您尝试插入相同的分区/行键两次。查看更新示例here
【解决方案2】:

如果您想使用 DynamicTableEntity,因为在编译时您不知道消息中将包含哪些数据,并且您意识到表绑定不再适用于 DynamicTableEntities,您可以使用以下方法:

private static async Task ProcessMessage(string message, DateTime enqueuedTime)
{
    var deviceData = JsonConvert.DeserializeObject<JObject>(message);

    var dynamicTableEntity = new DynamicTableEntity();
    dynamicTableEntity.RowKey = enqueuedTime.ToString("yyyy-MM-dd HH:mm:ss.fff");

    foreach (KeyValuePair<string, JToken> keyValuePair in deviceData)
    {
        if (keyValuePair.Key.Equals("MyPartitionKey"))
        {
            dynamicTableEntity.PartitionKey = keyValuePair.Value.ToString();
        }
        else if (keyValuePair.Key.Equals("Timestamp")) // if you are using a parameter "Timestamp" it has to be stored in a column named differently because the column "Timestamp" will automatically be filled when adding a line to table storage
        {
            dynamicTableEntity.Properties.Add("MyTimestamp", EntityProperty.CreateEntityPropertyFromObject(keyValuePair.Value));
        }
        else
        {
            dynamicTableEntity.Properties.Add(keyValuePair.Key, EntityProperty.CreateEntityPropertyFromObject(keyValuePair.Value));
        }
    }

    CloudStorageAccount storageAccount = CloudStorageAccount.Parse("myStorageConnectionString");
    CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
    CloudTable table = tableClient.GetTableReference("myTableName"); 
    table.CreateIfNotExists();

    var tableOperation = TableOperation.Insert(dynamicTableEntity);
    await table.ExecuteAsync(tableOperation);
}

【讨论】:

    猜你喜欢
    • 2022-08-12
    • 1970-01-01
    • 2018-01-11
    • 1970-01-01
    • 2020-09-04
    • 2021-10-08
    • 2020-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多