如何使用Automapper映射两个不同的数据类型字段?

时间:2019-04-10 11:15:09

标签: c# types expression automapper

我试图通过ProjectTo IQueryable使用Automapper映射具有源子级集合的对象的字段,如下所示:

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

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

模型如下:

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

预期结果: 由于该集合仅包含字符串值,但我需要根据字段名称映射不同的数据类型。

实际结果: 但是当我尝试应用转换时,由于sql查询不支持此转换,因此queryable引发异常。

1 个答案:

答案 0 :(得分:1)

您可以使用AutoMapper的Custom Type Converters

例如,AutoMapper不知道从字符串到整数的任何映射,因此要为这些类型创建映射,我们必须提供一个自定义类型转换器。这可以通过使用ConvertUsing()方法来实现。

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

上面的示例说明了如何转换intbooldecimal。对于DateTime,我们将使用ITypeConverter

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

然后定义一个自定义转换:

public class DateTimeTypeConverter : ITypeConverter<string, DateTime>
{
    public DateTime Convert(source)
    {
        return Convert.ToDateTime(source);
    }
}