Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

automapper

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?

like image 979
DJB Avatar asked Feb 15 '16 16:02

DJB


People also ask

Can AutoMapper map collections?

Polymorphic element types in collectionsAutoMapper supports polymorphic arrays and collections, such that derived source/destination types are used if found.

How AutoMapper is implemented in MVC?

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.


2 Answers

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.

like image 86
Jason Richmeier Avatar answered Oct 12 '22 04:10

Jason Richmeier


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);   
like image 28
Xtian11 Avatar answered Oct 12 '22 04:10

Xtian11