簡體   English   中英

AutoMapper:將多個屬性映射為一個

[英]AutoMapper: mapping many properties into one

場景如下:我收到一條包含大量變量的消息,數百個。 我需要將此寫入Azure Table存儲,其中分區鍵是單個變量的名稱,值將映射到例如Value。

假設有效載荷如下所示:

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可以提供幫助。

它們總是相同的變量嗎? 一種不同的方法可能是使用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

問題是要映射這些屬性,這是對的嗎?

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來映射其余屬性(在源和目標中具有相同名稱),以避免創建數百個配置映射。 或者只是將payloaddynamic並手動映射。

您可以使用SDK中的TableEntity.Flatten方法使用1-2行代碼從Payload對象創建DynamicTableEntity,或者如果您還擔心ICollection類型屬性,則使用ObjectFlattenerRecomposer Nuget包。 將其分配PK / RK並將展平的Payload對象作為DynamicTableEntity寫入表中。 當您回讀它時,將其讀作DynamicTableEntity,您可以使用TableEntity.ConvertBack方法重新創建原始對象。 甚至不需要那個中間表類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM