1

场景如下:我收到一条包含很多变量的消息,数百个。我需要将此写入 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; }
}

为了将其写入表存储,我需要

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 可以帮忙。

4

3 回答 3

0

问题是映射这些属性,对吗?

Value = value (payload.Foo or payload.Rpm or payload.Temp),
Signal = primarykey/Name of variable ("foo" or "rmp" or "temp"),

这种条件映射可以通过反射完成:

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();
}

您可以使用 call 映射其余属性(在源和目标中具有相同的名称),AutoMapper.Mapper.DynamicMap而不是AutoMapper.Mapper.Map避免创建数百个配置映射。或者只是将您的投射payloaddynamic并手动映射它。

于 2016-05-18T12:08:20.070 回答
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
于 2016-05-18T10:20:16.820 回答
0

您可以使用 SDK 中的 TableEntity.Flatten 方法使用 1-2 行代码从 Payload 对象创建 DynamicTableEntity,如果您还担心 ICollection 类型属性,则可以使用 ObjectFlatenerRecomposer Nuget 包。为其分配 PK/RK 并将展平的 Payload 对象作为 DynamicTableEntity 写入表中。当您读回它时,将其读取为 DynamicTableEntity 并且您可以使用 TableEntity.ConvertBack 方法重新创建原始对象。甚至不需要那个中间表类。

于 2018-06-29T23:14:47.553 回答