AutoMapper:将多个属性映射为一个

时间:2016-05-18 09:45:13

标签: c# azure automapper-4

场景如下:我收到一条包含大量变量的消息,数百个。我需要将此写入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可以提供帮助。

3 个答案:

答案 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类。