我试图通过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引发异常。
答案 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));
});
上面的示例说明了如何转换int
,bool
和decimal
。对于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);
}
}