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