Home > database >  AutoMapper - Map a complex object to list of flat objects
AutoMapper - Map a complex object to list of flat objects

Time:09-13

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

CodePudding user response:

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

  • Related