简体   繁体   中英

AutoMapper - Map a complex object to list of flat objects

How can I map a complex object to a list of flat objects using the AutoMapper? I want to convert list of fields to another list of objects keeping symbol as well. I've tried to use ITypeConverter from the AutoMapper documentation, but still not worked.

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; }
}

Consider a complex object:

{
  "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"
}

So, I expect convert to a list of objects like:

Destination:

[
  {
    "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  
  }
]

Challenging yet interesting question.

From my perspective, I would extract the object from the list and convert it into the Dictionary .

With the AutoMapper tools, you need these two concepts:

public class SourceToListDestinationTypeConverter : ITypeConverter<Source, List<Destination>>
{
    public List<Destination> Convert(Source source, List<Destination> destination, ResolutionContext context)
    {
        List<Destination> result = new List<Destination>();
                              
        foreach (var record in source.Records.Record)
        {
            Dictionary<string, object> fieldDict = record.Fields.Field
                .ToDictionary(x => x.Name, x => (object)x.Value);

            fieldDict.Add(nameof(Destination.Symbol), record.Req_sym);

            result.Add(context.Mapper.Map<Destination>(fieldDict));
        }
                                
        return result;
    }
}

Your MappingConfiguration or Mapping Profile should be looked as below:

MapperConfiguration _config = new MapperConfiguration(config => 
{       
    config.CreateMap<Source, List<Destination>>()
        .ConvertUsing<SourceToListDestinationTypeConverter>();
});

Demo @ .NET Fiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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