Я получаю следующее исключение, когда пытаюсь вызвать Mapper.Map в своем приложении:
AutoMapper.AutoMapperMappingException.
Mapping types:
Double -> Double
System.Double -> System.Double
Destination path:
Address.Latitude
Source value:
42.250287
System.InvalidCastException. Unable to cast object of type 'Acme.Order' to type 'Acme.Address'.
Помимо очевидного разочарования в связи с ошибкой, указывающей, что он не может отображать объекты одного и того же типа (и при этом примитивные типы), факт в том, что я НИКОГДА не сопоставляю тип «Acme.Order» с типом «Acme.Address»!
Вот фактический используемый вызов:
var order = Mapper.Map<IDataRecord, Order>(theDataReader);
Моя объектная модель выглядит так:
public class Order
{
public Address Address { get; set; }
public Int32 Number { get; set; }
public PhoneNumber PhoneNumber { get; set; }
}
public class Address
{
public String City { get; set; }
public Double Latitude { get; set; }
public Double Longitude { get; set; }
public Int32 Number { get; set; }
public String PostalCode { get; set; }
public String State { get; set; }
public String Street { get; set; }
}
public class PhoneNumber
{
public String Extension { get; set; }
public String Number { get; set; }
}
И у меня есть следующая конфигурация, определенная в моем приложении:
CreateMap<IDataRecord, Address>()
.ForMember(target => target.Latitude, opt => opt.MapFrom(record => GetDoubleFrom(record, "Latitude", 0)))
.ForMember(target => target.Longitude, opt => opt.MapFrom(record => GetDoubleFrom(record, "Longitude", 0)))
;
CreateMap<IDataRecord, PhoneNumber>()
.ForMember(target => target.Extension, opt => opt.MapFrom(record => GetStringFrom(record, "Extension", String.Empty)))
.ForMember(target => target.Number, opt => opt.MapFrom(record => GetStringFrom(record, "PhoneNumber", String.Empty)))
;
CreateMap<IDataRecord, Order>()
.ForMember(target => target.Address, opt => opt.ResolveUsing(record => Mapper.Map<IDataRecord, Address>(record)))
.ForMember(target => target.PhoneNumber, opt => opt.ResolveUsing(record => Mapper.Map<IDataRecord, PhoneNumber>(record)))
;
С помощью этих вспомогательных методов:
private Double GetDoubleFrom(IDataRecord record, String name, Double defaultValue)
{
return (record.Contains(name) && !record.IsDbNull(name)) ? record.GetDouble(name) : defaultValue;
}
private String GetStringFrom(IDataRecord record, String name, String defaultValue)
{
return (record.Contains(name) && !record.IsDbNull(name)) ? record.GetString(name) : defaultValue;
}
(У меня есть методы расширения в IDataRecord, которые принимают имя поля, получают порядковый номер и возвращают значение, используя стандартные методы, но не отображают их для краткости.)
Что-то из этого проливает свет на то, что вызывает сбой?
(Кстати, я использую AutoMapper v2.1.267)