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