I am trying to map a DataTable to an object (DTO) using AutoMappers DynamicMap feature.
DataTable dt;
dt = new dalAllInvestors().InvestorNameSearch(investorNameSearch);
// Look at DynamicMap - Urgent
List<dtoAPISimpleInvestor> apiObject = AutoMapper.Mapper.DynamicMap<IDataReader, List<dtoAPISimpleInvestor>>(
dt.CreateDataReader());
return apiObject;
public class dtoAPISimpleInvestor
{
public int FirmID { get; set; }
public string FirmName { get; set; }
public string Type { get; set; }
public string Location { get; set; }
}
dt
returns 10 rows but when you look at the apiObject it returns no rows and this does not seem to make any sense. I have been looking at this for a while now and after googling it looks like I am doing it correctly.
The correct columns are in the dt when its return which map to the dtoAPISimpleInvestor
Can somebody please help me?
Polymorphic element types in collectionsAutoMapper supports polymorphic arrays and collections, such that derived source/destination types are used if found.
First install the NuGet Package Manager in your Visual Studio IDE. Once done, go to "Tools" -> "Library Packet Manager" -> "Packet manager Console". Press Enter. This will install AutoMapper and the next time you open MVC application in Visual Studio, it will automatically add a DLL reference to the project.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With