当我尝试在我的应用程序中调用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。地址“!
以下是使用的实际通话:
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)
答案 0 :(得分:1)
我无法直接重新创建它,因为它缺少一些信息(例如IDataRecord
接口的具体类,theDataReader
的内容等)。但是,首先检查是确保您的映射是正确的。你用AssertConfigurationIsValid
测试它吗?
例如,如果您有以下AutoMapper配置文件:
public class MyProfile : Profile
{
public override string ProfileName
{
get
{
return "MyProfile";
}
}
protected override void Configure()
{
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)));
}
}
这个单元测试会通过吗?
[Test]
public void AutoMapper_Configuration_IsValid()
{
Mapper.Initialize(m => m.AddProfile<MyProfile>());
Mapper.AssertConfigurationIsValid();
}
<强>更新强>
你能试试吗
CreateMap<IDataRecord, Order>()
.ForMember(
target => target.Address,
opt => opt.MapFrom(record => Mapper.Map<IDataRecord, Address>(record)))
.ForMember(
target => target.PhoneNumber,
opt => opt.MapFrom(record => Mapper.Map<IDataRecord, PhoneNumber>(record)));