web-dev-qa-db-fra.com

Utilisation d'AutoMapper pour mapper un DataTable sur un objet (DTO)

J'essaie de mapper un DataTable sur un objet (DTO) à l'aide de la fonctionnalité AutoMappers DynamicMap. 

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 renvoie 10 lignes, mais lorsque vous regardez l'apiObject, il ne renvoie aucune ligne et cela ne semble avoir aucun sens. Cela fait un moment que je suis en train de regarder ça et après avoir googlé, il semble que je le fasse correctement. 

Les colonnes correctes sont dans le dt lors de son retour, qui mappe à la dtoAPISimpleInvestor

Quelqu'un peut-il m'aider s'il vous plaît?

10
DJB

Que diriez-vous de quelque chose comme ce qui suit ...

Profil AutoMapper

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: J'utilise le type DataRow comme source et non IDataReader (plus d'informations à ce sujet ci-dessous).

Utiliser le profil

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

L'objet result doit contenir le nombre correct d'objets dtoAPISimpleInvestor avec les données correctes.

NOTE: l'appel à mapper.Map prend un objet de type List<DataRow> pouvant être obtenu à partir de l'objet DataTable à l'aide de l'instruction new List<DataRow>(dataTable.Rows.OfType<DataRow>()); (puisque la propriété Rows de l'objet DataTable est une collection qui implémente IEnumerable mais pas IEnumerable<T> ).

Ce n'est probablement pas la solution seulement mais j'ai validé que cela fonctionne.

En remarque, j’ai remarqué que la méthode DynamicMap à laquelle vous avez fait référence a été marquée comme obsolète dans la dernière version de la bibliothèque. Vous voudrez peut-être éviter de l’utiliser.

14
Jason Richmeier

Cela a fonctionné pour moi: La version de automapper est 3.1.1 télécharger à partir de nugget

using AutoMapper;

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

Méthode d'appel comme ceci:

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