场景如下:我收到一条包含大量变量的消息,数百个。我需要将此写入Azure表存储,其中分区键是各个变量的名称,并且值被映射到例如值。
假设有效载荷如下所示:
public class Payload
{
public long DeviceId { get; set; }
public string Name { get; set; }
public double Foo { get; set; }
public double Rpm { get; set; }
public double Temp { get; set; }
public string Status { get; set; }
public DateTime Timestamp { get; set; }
}
我的TableEntry是这样的:
public class Table : TableEntity
{
public Table(string partitionKey, string rowKey)
{
this.PartitionKey = partitionKey;
this.RowKey = rowKey;
}
public Table() {}
public long DeviceId { get; set; }
public string Name { get; set; }
public double Value { get; set; }
public string Signal { get; set; }
public string Status { get; set; }
}
为了将其写入Table存储,我需要
var table = new Table(primaryKey, payload.Timestamp.ToString(TimestampFormat))
{
DeviceId = payload.DeviceId,
Name = payload.Name,
Status = payload.Status,
Value = value (payload.Foo or payload.Rpm or payload.Temp),
Signal = primarykey/Name of variable ("foo" or "rmp" or "temp"),
Timestamp = payload.Timestamp
};
var insertOperation = TableOperation.Insert(table);
await this.cloudTable.ExecuteAsync(insertOperation);
我不想复制900次(或者有效载荷消息中发生了多少变量;这是一个固定的数字)。
我可以创建一个创建表的方法,但我仍然需要调用900次。
我想也许AutoMapper可以提供帮助。
答案 0 :(得分:0)
它们总是相同的变量吗?一种不同的方法可能是使用DynamicTableEntity,你基本上有一个TableEntity,你可以在RowKey / PartitionKey Duo之后填写所有其他字段:
var tableEntity = new DynamicTableEntity();
tableEntity.PartitionKey = "partitionkey";
tableEntity.RowKey = "rowkey";
dynamic json = JsonConvert.DeserializeObject("{bunch:'of',stuff:'here'}");
foreach(var item in json)
{
tableEntity.Properties.Add(item.displayName, item.value);
}
// Save etc
答案 1 :(得分:0)
问题是要映射这些属性,这是对吗?
Value = value (payload.Foo or payload.Rpm or payload.Temp),
Signal = primarykey/Name of variable ("foo" or "rmp" or "temp"),
这种条件映射可以通过Reflection:
完成object payload = new A { Id = 1 };
object value = TryGetPropertyValue(payload, "Id", "Name"); //returns 1
payload = new B { Name = "foo" };
value = TryGetPropertyValue(payload, "Id", "Name"); //returns "foo"
public object TryGetPropertyValue(object obj, params string[] propertyNames)
{
foreach (var name in propertyNames)
{
PropertyInfo propertyInfo = obj.GetType().GetProperty(name);
if (propertyInfo != null) return propertyInfo.GetValue(obj);
}
throw new ArgumentException();
}
您可以使用AutoMapper.Mapper.DynamicMap
调用而不是AutoMapper.Mapper.Map
映射其余属性(源和目标中的名称相同),以避免创建数百个配置映射。或者只是将payload
投射到dynamic
并手动映射。
答案 2 :(得分:0)
您可以使用SDK中的TableEntity.Flatten方法使用1-2行代码从有效负载对象创建DynamicTableEntity,或者如果您还担心ICollection类型属性,请使用ObjectFlattenerRecomposer Nuget包。为其分配PK / RK并将展平的Payload对象作为DynamicTableEntity写入表中。读回时,将其读为DynamicTableEntity,然后可以使用TableEntity.ConvertBack方法重新创建原始对象。甚至不需要中间的Table类。