AutoMapper 从 DataTable 到 DTO
AutoMapper from DataTable to DTO
我在 ADO.NET 调用期间填充了一个 DataSet
,然后我想使用 AutoMapper 将其转换为 DTO。
我已经为我们的许多 DTO 类型定义了一个通用映射器:
IMapper DataReaderMapper = new MapperConfiguration(cfg => {
cfg.AddDataReaderMapping();
cfg.CreateMap<IDataReader, MyApp>();
cfg.CreateMap<IDataReader, MyRole>();
cfg.CreateMap<IDataReader, MyBill>();
}).CreateMapper();
这在映射所有这些 DTO 类型时效果很好:
var apps = DataReaderMapper.Map<IList<AppDTO>>(dataSet.Tables[0].CreateDataReader());
但是,我现在添加了这个映射:
cfg.CreateMap<IDataReader, Money>();
但是,此 Money
类型包含两个 float
属性,它们似乎给 AutoMapper 带来了一些问题,但以下例外:
Error mapping types.
Mapping types: IDataReader -> Money System.Data.IDataReader ->
Common.Models.Money
Type Map configuration: IDataReader -> Money System.Data.IDataReader
-> Common.Models.Money
Destination Member:
Amount
其中包含这个 InnerException
:
Specified cast is not valid.
我已尝试指定自定义值映射:
cfg.CreateMap<IDataReader, Money>().ForMember(x => x.Amount, opt => opt.MapFrom(rdr => Convert.ToDouble(rdr["Amount"])));
但这甚至没有改变异常。
我如何告诉 AutoMapper 这个 Money
类型应该通过从 SQL 字段 float Amount
转换来填充它的 float Amount
属性?
感谢@lucian-bargaoanu link。这促使我再次查看导致提供解析器的文档。
我现在已经用一些自定义解析器充实了映射:
IMapper DataReaderMapper = new MapperConfiguration(cfg => {
cfg.AddDataReaderMapping();
cfg.CreateMap<IDataReader, MyApp>();
cfg.CreateMap<IDataReader, MyRole>();
cfg.CreateMap<IDataReader, MyBill>();
cfg.CreateMap<IDataReader, Money>()
.ForMember(dest => dest.Amount, opt => opt.MapFrom<MoneyAmountResolver>())
.ForMember(dest => dest.SubTotal, opt => opt.MapFrom<MoneySubTotalResolver>());
}).CreateMapper();
解析器很小 类:
public class MoneyAmountResolver: IValueResolver<IDataReader, Money, float>
{
public float Resolve(IDataReader source, Moneydestination, float member, ResolutionContext context)
{
return (float)Convert.ToDouble(source["Amount"]);
}
}
public class MoneySubTotalResolver: IValueResolver<IDataReader, Money, float>
{
public float Resolve(IDataReader source, Moneydestination, float member, ResolutionContext context)
{
return (float)Convert.ToDouble(source["SubTotal"]);
}
}
我在 ADO.NET 调用期间填充了一个 DataSet
,然后我想使用 AutoMapper 将其转换为 DTO。
我已经为我们的许多 DTO 类型定义了一个通用映射器:
IMapper DataReaderMapper = new MapperConfiguration(cfg => {
cfg.AddDataReaderMapping();
cfg.CreateMap<IDataReader, MyApp>();
cfg.CreateMap<IDataReader, MyRole>();
cfg.CreateMap<IDataReader, MyBill>();
}).CreateMapper();
这在映射所有这些 DTO 类型时效果很好:
var apps = DataReaderMapper.Map<IList<AppDTO>>(dataSet.Tables[0].CreateDataReader());
但是,我现在添加了这个映射:
cfg.CreateMap<IDataReader, Money>();
但是,此 Money
类型包含两个 float
属性,它们似乎给 AutoMapper 带来了一些问题,但以下例外:
Error mapping types.
Mapping types: IDataReader -> Money System.Data.IDataReader -> Common.Models.Money
Type Map configuration: IDataReader -> Money System.Data.IDataReader -> Common.Models.Money
Destination Member:
Amount
其中包含这个 InnerException
:
Specified cast is not valid.
我已尝试指定自定义值映射:
cfg.CreateMap<IDataReader, Money>().ForMember(x => x.Amount, opt => opt.MapFrom(rdr => Convert.ToDouble(rdr["Amount"])));
但这甚至没有改变异常。
我如何告诉 AutoMapper 这个 Money
类型应该通过从 SQL 字段 float Amount
转换来填充它的 float Amount
属性?
感谢@lucian-bargaoanu link。这促使我再次查看导致提供解析器的文档。
我现在已经用一些自定义解析器充实了映射:
IMapper DataReaderMapper = new MapperConfiguration(cfg => {
cfg.AddDataReaderMapping();
cfg.CreateMap<IDataReader, MyApp>();
cfg.CreateMap<IDataReader, MyRole>();
cfg.CreateMap<IDataReader, MyBill>();
cfg.CreateMap<IDataReader, Money>()
.ForMember(dest => dest.Amount, opt => opt.MapFrom<MoneyAmountResolver>())
.ForMember(dest => dest.SubTotal, opt => opt.MapFrom<MoneySubTotalResolver>());
}).CreateMapper();
解析器很小 类:
public class MoneyAmountResolver: IValueResolver<IDataReader, Money, float>
{
public float Resolve(IDataReader source, Moneydestination, float member, ResolutionContext context)
{
return (float)Convert.ToDouble(source["Amount"]);
}
}
public class MoneySubTotalResolver: IValueResolver<IDataReader, Money, float>
{
public float Resolve(IDataReader source, Moneydestination, float member, ResolutionContext context)
{
return (float)Convert.ToDouble(source["SubTotal"]);
}
}