Как отобразить два разных поля типа данных с помощью Automapper? - PullRequest
3 голосов
/ 10 апреля 2019

Я пытаюсь сопоставить поля объекта с дочерней коллекцией источника с помощью Automapper через ProjectTo IQueryable следующим образом:

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-запрос не поддерживает это преобразование..

1 Ответ

1 голос
/ 10 апреля 2019

Вы можете использовать AutoMapper Пользовательские преобразователи типов .

AutoMapper не знает ни о каком сопоставлении от строки до int, например, поэтому для создания карт для этих типов мы должны предоставить специальный преобразователь типов. Это может быть достигнуто с помощью метода 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);
    }
}
...