Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to map two different datatype fields using Automapper?

I am trying to map fields of an object with child collection of source using Automapper through ProjectTo IQueryable as following:

var map2 = cfg.CreateMap<SourceModel, DestinationModel>(); 

map2.ForMember(fieldName, opt => opt.MapFrom(source => source.CustomFieldValues.FirstOrDefault(f => f.Name == fieldName).Value));

Models are as following:

public class SourceModel
{
  public IEnumerable<CustomFieldValue> CustomFieldValues { get; set; }
}

public class CustomFieldValue
{

    public string Name { get; set; }
    public string Value { get; set; }
}

public class DestinationModel
{
    public string _CUSTOM_Test { get; set; }
    public int _CUSTOM_Mynumber { get; set; }
    public DateTime _CUSTOM_mydate { get; set; }
    public bool _CUSTOM_mybool { get; set; }
    public decimal _CUSTOM_numberdec { get; set; }
    public int _CUSTOM_numint { get; set; }
    public int _CUSTOM_numper { get; set; }
    public DateTime _CUSTOM_mydate2 { get; set; }
    public DateTime _CUSTOM_mydate3 { get; set; }
    public DateTime _CUSTOM_mydate4 { get; set; }
    public int _CUSTOM_mynum2 { get; set; }
}

Expected Result: As the collection contains only string values but I need to map with different datatypes based on field name.

Actual Result: But when I try to apply conversion then queryable throws exception because sql query doesn't support this conversion.

like image 326
Pankaj Kaushik Avatar asked Oct 28 '25 05:10

Pankaj Kaushik


1 Answers

You can use AutoMapper's Custom Type Converters.

AutoMapper does not know about any mapping from string to int for example so to create maps for these types, we must supply a custom type converter. This can be achieved by using ConvertUsing() method.

Mapper.Initialize(configuration =>
{
    configuration.CreateMap<string, int>().ConvertUsing(s => Convert.ToInt32(s));
    configuration.CreateMap<string, DateTime>().ConvertUsing(s => new DateTimeTypeConverter().Convert(s));
    configuration.CreateMap<string, bool>().ConvertUsing(s => Convert.ToBoolean(s));
    configuration.CreateMap<string, decimal>().ConvertUsing(s => Convert.ToDecimal(s));
    configuration.CreateMap<SourceModel, DestinationModel>()
        .ForMember("_CUSTOM_Mynumber", opt => opt.MapFrom(src => src.CustomFieldValues.FirstOrDefault(x => x.Name == "_CUSTOM_Mynumber").Value));
});

The example above shows how we can convert int, bool, and decimal. For DateTime, we'll use ITypeConverter.

public interface ITypeConverter<in TSource, TDestination>
{
    TDestination Convert(TSource source);
}

Then define a custom convertion:

public class DateTimeTypeConverter : ITypeConverter<string, DateTime>
{
    public DateTime Convert(string source)
    {
        return Convert.ToDateTime(source);
    }
}
like image 116
TimAlonso Avatar answered Oct 29 '25 18:10

TimAlonso



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!