You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用AutoMapper将复杂对象映射为扁平对象列表?

使用AutoMapper将复杂对象转换为扁平对象列表

我需要用AutoMapper把复杂的Source对象转换成扁平的对象列表,同时保留Symbol信息。尝试了官方文档里的ITypeConverter接口,但映射没成功。相关C#类定义、示例数据和期望的转换结果如下:

相关C#类定义

public class Source
{
    public Request Request { get; set; }
    public Error Error { get; set; }
    public Records Records { get; set; }
    public string Service { get; set; }
}

public class Records
{
    public List<Record> Record { get; set; }
}

public class Fields
{
    public List<Field> Field { get; set; }
}

public class Field
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }
}

public class Request
{
    public string RequestedSymbols { get; set; }
    public string RequestedFields { get; set; }
    public string Host { get; set; }
    public string Id { get; set; }
}

public class Error
{
    public string Code { get; set; }
    public string Description { get; set; }
}

public class Record
{
    public Fields Fields { get; set; }
    public string Req_sym { get; set; }
    public string Key { get; set; }
    public string Stale { get; set; }
}

示例复杂对象数据

{
  "Request": {
    "RequestedSymbols": "ABC,BCD,CDE",
    "RequestedFields": "ASK,BID,LAST",
    "Host": "XYZ",
    "Id": "123"
  },
  "Error": {
    "Code": "0",
    "Description": ""
  },
  "Records": {
    "Record": [
      {
        "Fields": {
          "Field": [
            {
              "Id": "200",
              "Name": "ASK",
              "Value": "43.75"
            },
            {
              "Id": "100",
              "Name": "BID",
              "Value": "43.73"
            },
            {
              "Id": "300",
              "Name": "LAST",
              "Value": "43.73"
            }
          ]
        },
        "Req_sym": "ABC",
        "Key": "ABC",
        "Stale": ""
      },
      {
        "Fields": {
          "Field": [
            {
              "Id": "200",
              "Name": "ASK",
              "Value": "76.18"
            },
            {
              "Id": "100",
              "Name": "BID",
              "Value": "76.17"
            },
            {
              "Id": "300",
              "Name": "LAST",
              "Value": "76.19"
            }
          ]
        },
        "Req_sym": "BCD",
        "Key": "BCD",
        "Stale": ""
      },
      {
        "Fields": {
          "Field": [
            {
              "Id": "200",
              "Name": "ASK",
              "Value": "16.34"
            },
            {
              "Id": "100",
              "Name": "BID",
              "Value": "16.33"
            },
            {
              "Id": "300",
              "Name": "LAST",
              "Value": "16.33"
            }
          ]
        },
        "Req_sym": "CDE",
        "Key": "CDE",
        "Stale": ""
      }
    ]
  },
  "Service": "XYZ"
}

期望转换后的扁平对象列表

[
  {
    "Symbol": "ABC",
    "ASK": 43.75,
    "BID": 43.73,
    "LAST": 43.73 
  },
  {
    "Symbol": "BCD",
    "ASK": 76.18,
    "BID": 76.17,
    "LAST": 76.19  
  },
  {
    "Symbol": "CDE",
    "ASK": 16.34,
    "BID": 16.33,
    "LAST": 16.33  
  }
]

解决方案

1. 定义目标DTO类

先创建匹配期望结构的DTO:

public class SymbolPriceDto
{
    public string Symbol { get; set; }
    public decimal ASK { get; set; }
    public decimal BID { get; set; }
    public decimal LAST { get; set; }
}

2. 实现自定义类型转换器

因为要从Source转换为List<SymbolPriceDto>,需要实现ITypeConverter<Source, List<SymbolPriceDto>>,在转换器里处理嵌套结构的解析逻辑:

public class SourceToSymbolPriceListConverter : ITypeConverter<Source, List<SymbolPriceDto>>
{
    public List<SymbolPriceDto> Convert(Source source, List<SymbolPriceDto> destination, ResolutionContext context)
    {
        var result = new List<SymbolPriceDto>();
        if (source?.Records?.Record == null) return result;

        foreach (var record in source.Records.Record)
        {
            var dto = new SymbolPriceDto
            {
                Symbol = record.Req_sym
            };

            foreach (var field in record.Fields.Field)
            {
                if (decimal.TryParse(field.Value, out var value))
                {
                    switch (field.Name)
                    {
                        case "ASK":
                            dto.ASK = value;
                            break;
                        case "BID":
                            dto.BID = value;
                            break;
                        case "LAST":
                            dto.LAST = value;
                            break;
                    }
                }
            }

            result.Add(dto);
        }

        return result;
    }
}

3. 配置AutoMapper映射

在AutoMapper配置中注册这个自定义转换器:

var configuration = new MapperConfiguration(cfg =>
{
    cfg.CreateMap<Source, List<SymbolPriceDto>>()
       .ConvertUsing<SourceToSymbolPriceListConverter>();
});

// 可选:验证配置合法性,排查映射问题
configuration.AssertConfigurationIsValid();

var mapper = configuration.CreateMapper();

4. 执行映射

现在可以直接完成转换:

Source sourceData = // 你的Source对象实例
List<SymbolPriceDto> flatList = mapper.Map<List<SymbolPriceDto>>(sourceData);

关键注意点

  • 转换器中加入了空值判断,避免空引用异常
  • 使用decimal.TryParse确保字段值转换的类型安全
  • 后续新增字段时,只需在DTO类和转换器的switch分支中添加对应处理逻辑即可

内容的提问来源于stack exchange,提问作者Narendra Jangir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 19:40:18