c# - Automapper - 将上层属性作为参数传递给下层地图
问题描述
我希望能够访问注释映射部分中的 ShipmentIdentifier 属性,这样我就可以成功运行下面的断言语句。下面是我的映射器的简化版本。在映射 WeightUnit 时如何传递 ShipmentIdentifier 属性?
using AutoMapper;
using System.Collections.Generic;
using Xunit;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
IMapper mapper = new MapperConfiguration(cfg =>
{
cfg.AddProfile(typeof(PrintLabelCommandMappingProfile));
}).CreateMapper();
CarrierLabelPrintedMessage message = new CarrierLabelPrintedMessage
{
ShipmentIdentifier = "AB1234",
Cartons = new List<Carton>
{
new Carton
{
TrackingNumber = "TestTrackingNumber",
LabelData =
new LabelData
{
Weight = 5,
WeightUnit = "none"
}
}
}
};
var command = mapper.Map<PrintLabelCommand>(message);
Assert.Equal(command.ShipmentUnits[0].Weight.Unit, WeightUnit.None);
}
public class PrintLabelCommandMappingProfile : Profile
{
public PrintLabelCommandMappingProfile()
{
CreateMap<CarrierLabelPrintedMessage, PrintLabelCommand>()
.ForMember(cmd => cmd.ShipmentId, exp => exp.MapFrom(msg => msg.ShipmentIdentifier))
.ForMember(cmd => cmd.ShipmentUnits, exp => exp.MapFrom(msg => msg.Cartons));
CreateMap<Carton, ShipmentUnit>()
.ForMember(su => su.Id, exp => exp.MapFrom(c => c.TrackingNumber))
.ForPath(su => su.Weight.Amount, exp => exp.MapFrom(c => c.LabelData.Weight))
.ForPath(su => su.Weight.Unit, exp => exp.MapFrom(c => c.LabelData.WeightUnit));
CreateMap<string, WeightUnit>().ConvertUsing((str, _) =>
{
// I want to have ShipmentIdentifier field to be accessible in the upper level to implement the mapping logic here as below
//if (ShipmentIdentifier.StartsWith("AB")) // it's "AB1234" in the sample
// return WeightUnit.None;
//else
return WeightUnit.Grams;
});
}
}
public class CarrierLabelPrintedMessage
{
public string ShipmentIdentifier { get; set; }
public List<Carton> Cartons { get; set; }
}
public class PrintLabelCommand
{
public string ShipmentId { get; set; }
public List<ShipmentUnit> ShipmentUnits { get; set; }
}
public class Carton
{
public string TrackingNumber { get; set; }
public LabelData LabelData { get; set; }
}
public class LabelData
{
public double Weight { get; set; }
public string WeightUnit { get; set; }
}
public class ShipmentUnit
{
public string Id { get; set; }
public Weight Weight { get; set; }
}
public class Weight
{
public double Amount { get; set; }
public WeightUnit Unit { get; set; }
}
public enum WeightUnit
{
None,
Grams,
Kilograms
}
}
}
有什么想法吗?
解决方案
您可以使用AfterMap()
映射CreateMap<CarrierLabelPrintedMessage, PrintLabelCommand>()
来“修复”基于 中可用信息的映射CarrierLabelPrintedMessage
。映射可能如下所示:
CreateMap<CarrierLabelPrintedMessage, PrintLabelCommand>()
.ForMember(cmd => cmd.ShipmentId, exp => exp.MapFrom(msg => msg.ShipmentIdentifier))
.ForMember(cmd => cmd.ShipmentUnits, exp => exp.MapFrom(msg => msg.Cartons))
.AfterMap((src, target) => {
WeightUnit targetValue = WeightUnit.Grams;
if (src.ShipmentIdentifier.StartsWith("AB"))
{
targetValue = WeightUnit.None;
}
foreach (ShipmentUnit shipmentUnit in target.ShipmentUnits)
{
shipmentUnit.Weight.Unit = targetValue;
}
});
推荐阅读
- postgresql - 在 PostgreSQL 视图中包含一个 TIMESTAMP = NOW() 列
- javascript - 如何在javascript中将音频添加到10秒倒计时
- python - python嵌套while循环和日期时间
- python - Pygame 密钥约定
- node.js - 后端单元测试使用mocha和chai,每次测试前如何清库
- javascript - 在javascript中克隆数组时遇到问题,做出反应
- javascript - 如何在 JavaScript 中检查给定日期是本周还是上周
- mysql - SQL 交集错误 ERROR 1064 (42000):
- python - 如何在 matplotlib 工具栏中设置鼠标坐标的大小?
- php - 我可以通过 socket_sendmsg (sendmsg) 将 TCP 套接字资源传递给 AF_UNIX 本地套接字吗?如果可以,如何