繁体   English   中英

Automapper - 将简单列表映射到复杂的嵌套类型

[英]Automapper - mapping simple list to complex nested type

我有一个关于 Automapper 的问题,我有一个简单的对象列表,我必须在转换后的 DTO 对象中返回到前端,比方说,列表

List<Cars> list =
Cars
{
    public string PartCode { get; set; }
    public bool Enabled { get; set; }
    public string CarCode { get; set; }
    public int CarId { get; set; }
    public int PartId { get; set; }
}

我需要将它映射到对象:

public class CarsDTO
{
    public int CarId;
    public string CarCode;
    public List<PartsDTO> CarParts;
}

public class PartDTO
{
    public Part Id;
    public string PartCode;
    public bool Enabled;
}

和示例数据:

part_id part_code   car_id  car_code    enabled
1   WINDOW  1   MUSTANG true
2   WHEELS  1   MUSTANG true
3   BUMPER  2   MONDEO  true
4   HOOD    2   MONDEO  false
5   WINDSHIELD  2   MONDEO  true
6   TIRE    3   KA  true
7   STEERING_WHEEL  4   FOCUS   false
8   TRANSMISSION    4   FOCUS   true

并在 json 中映射后建议输出:

"parts": [
        {
            "carId": 1,
            "carCode": "MUSTANG",
            "carParts": [
                {
                    "id": 1,
                    "partCode": "WINDOW",
                    "enabled": true
                },
                {
                    "id": 2,
                    "partCode": "WHEELS",
                    "enabled": true
                }
            ]
        },
        {
            "carId": 2,
            "carCode": "MONDEO",
            "carParts": [
                {
                    "id": 3,
                    "partCode": "BUMPER",
                    "enabled": true
                },
                {
                    "id": 4,
                    "partCode": "HOOD",
                    "enabled": false
                },
                {
                    "id": 5,
                    "partCode": "WINDSHIELD",
                    "enabled": true
                }
            ]
        },
        {
            "carId": 3,
            "carCode": "KA",
            "carParts": [
                {
                    "id": 6,
                    "partCode": "TIRE",
                    "enabled": true
                },
            ]
        },
        {
            "carId": 4,
            "carCode": "FOCUS",
            "carParts": [
                {
                    "id": 7,
                    "partCode": "STEERING_WHEEL",
                    "enabled": false
                },
                {
                    "id": 8,
                    "partCode": "TRANSMISSION",
                    "enabled": true
                ]
        }
        ]

我设法使用以下查询在 Linq 中映射对象:

    List<CarParts> carParts = new List<CarParts>();

    List<CarPartsList> list = (from t in carParts
                                 group t by new { t.CarCode, t.CarId }
                                 into grp
                                 select new CarPartsList()
                                 {
                                     GroupCode = grp.Key.CarCode,
                                     GroupId = grp.Key.CarId,
                                     GroupRights = (from
                                                    carPart in carParts
                                                    where userRight.CarCode == grp.Key.CarCode
                                                    select new Part { Id = carPart.PartId, PartCode = carPart.Code, Enabled = carPart.Enabled }).ToList()
                                 }).ToList();

但是我正在处理的项目需要 Automapper 来转换 DTO 对象,我不知道解决方案:/我阅读了以下文档: https : //docs.automapper.org/en/stable/Nested-mappings.html但是示例中的docs 太简单了,我无法使用它。

这里最好的答案是不使用 AutoMapper,因为在这种情况下,它只会引入不必要的复杂性,而不是简化您的代码。 使用指南甚至指出:

除非目标类型是源类型的属性的扁平子集,否则不要使用 AutoMapper


然而...

如果您的项目需要在此处使用 AutoMapper,一种方法是定义一个自定义类型转换器,该转换器基本上执行与您在其他情况下所做的相同的 LINQ 投影:

public class CarPartConverter : ITypeConverter<IEnumerable<Cars>, IEnumerable<CarsDTO>>
{
    public IEnumerable<CarsDTO> Convert(IEnumerable<Cars> source, IEnumerable<CarsDTO> destination, ResolutionContext context)
    {
        return source
            .GroupBy(c => new {c.CarCode, c.CarId})
            .Select(g => new CarsDTO
            {
                CarCode = g.Key.CarCode,
                CarId = g.Key.CarId,
                CarParts = g.Select(v => new PartsDTO
                {
                    Id = v.PartId,
                    PartCode = v.PartCode,
                    Enabled = v.Enabled
                }).ToList()
            });
    }
}

这是使用该转换器的完整示例:

static void Main(string[] args)
{
    IMapper mapper = new MapperConfiguration(cfg => {
        cfg.CreateMap<IEnumerable<Cars>, IEnumerable<CarsDTO>>().ConvertUsing<CarPartConverter>();
    }).CreateMapper();

    List<Cars> cars = new List<Cars>
    {
        new Cars {PartId = 1, PartCode = "WINDOW", CarId = 1, CarCode = "MUSTANG", Enabled = true},
        new Cars {PartId = 2, PartCode = "WHEELS", CarId = 1, CarCode = "MUSTANG", Enabled = true},
        new Cars {PartId = 3, PartCode = "BUMPER", CarId = 2, CarCode = "MONDEO", Enabled = true}
    };

    IEnumerable<CarsDTO> dtos = mapper.Map<IEnumerable<CarsDTO>>(cars);

    Console.WriteLine(JsonConvert.SerializeObject(dtos, Formatting.Indented));
    Console.ReadLine();
}

这给出了以下结果:

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM