Using AutoMapper to Map a DataTable to an Object (DTO)

How about something like the following...

AutoMapper Profile

public sealed class SimpleInvestorProfile : Profile
{
  // This is the approach starting with version 5
  public SimpleInvestorProfile()
  {
      IMappingExpression<DataRow, dtoAPISimpleInvestor> mappingExpression;

    mappingExpression = CreateMap<DataRow, dtoAPISimpleInvestor>();
    mappingExpression.ForMember(d => d.FirmID, o => o.MapFrom(s => s["FirmID"]));
    mappingExpression.ForMember(d => d.FirmName, o => o.MapFrom(s => s["FirmName"]));
    mappingExpression.ForMember(d => d.Type, o => o.MapFrom(s => s["Type"]));
    mappingExpression.ForMember(d => d.Location, o => o.MapFrom(s => s["Location"]));

  }

  // this method is obsolete in version 5
  // protected override void Configure()
  // {
  //   IMappingExpression<DataRow, dtoAPISimpleInvestor> mappingExpression;

  //  mappingExpression = CreateMap<DataRow, dtoAPISimpleInvestor>();
  //  mappingExpression.ForMember(d => d.FirmID, o => o.MapFrom(s => s["FirmID"]));
  //  mappingExpression.ForMember(d => d.FirmName, o => o.MapFrom(s => s["FirmName"]));
  //   mappingExpression.ForMember(d => d.Type, o => o.MapFrom(s => s["Type"]));
  //  mappingExpression.ForMember(d => d.Location, o => o.MapFrom(s => s["Location"]));

  //  return;
 // }
}

NOTE : I am using the DataRow type as the source and not IDataReader (more on this below).

Using the Profile

MapperConfiguration configuration;

configuration = new MapperConfiguration(a => {a.AddProfile(new SimpleInvestorProfile());});

IMapper mapper;

mapper = configuration.CreateMapper();

List<dtoAPISimpleInvestor> result;

result = mapper.Map<List<DataRow>, List<dtoAPISimpleInvestor>>(rows);

The result object should contain the correct number of dtoAPISimpleInvestor objects with the correct data.

NOTE : The call to mapper.Map takes an object of type List<DataRow> which can be obtained from the DataTable object using the statement new List<DataRow>(dataTable.Rows.OfType<DataRow>()); (since the Rows property of the DataTable object is a collection that implements IEnumerable but not IEnumerable<T>).

This is likely not the only solution but I have validated that it works.

As a side note, I noticed that DynamicMap method that you referenced has been marked as obsolete in the latest version of the library so you may want to avoid using it.


This worked for me: Version of automapper is 3.1.1 download from nuget

using AutoMapper;

public List<T> ReadData<T>(DataTable dt)
{            
  return Mapper.DynamicMap<IDataReader, List<T>>(dt.CreateDataReader());                        
}

Call method like this:

DataTable dt = getPeopleDT();
List<PEOPLEDTO> peopleList = ReadData<PEOPLEDTO>(dt);   

Tags:

C#

Automapper