从 DataTable 到 DTO 的 AutoMapper

Posted

技术标签:

【中文标题】从 DataTable 到 DTO 的 AutoMapper【英文标题】:AutoMapper from DataTable to DTO 【发布时间】:2021-11-14 08:35:53 【问题描述】:

我在 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 带来了一些问题,但有以下例外:

错误映射类型。

映射类型:IDataReader -> Money System.Data.IDataReader -> Common.Models.Money

类型映射配置:IDataReader -> Money System.Data.IDataReader -> Common.Models.Money

目标成员:

金额

其中包含这个InnerException:

指定的转换无效。

我已尝试指定自定义值映射:

cfg.CreateMap<IDataReader, Money>().ForMember(x => x.Amount, opt => opt.MapFrom(rdr => Convert.ToDouble(rdr["Amount"])));

但这甚至没有改变异常。

我如何告诉 AutoMapper 这个 Money 类型应该通过从 SQL 字段 float Amount 转换来填充其 float Amount 属性?

【问题讨论】:

试试docs.automapper.org/en/latest/Custom-type-converters.html 【参考方案1】:

感谢@lucian-bargaoanu 提供链接。这促使我再次查看导致提供解析器的文档。

我现在用一些自定义解析器充实了映射:

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"]);
    

【讨论】:

以上是关于从 DataTable 到 DTO 的 AutoMapper的主要内容,如果未能解决你的问题,请参考以下文章

JPA 模式:从实体生成数据传输对象 DTO 并将 DTO 合并到数据库

如何创建从实体到 dto 的映射器,其中 dto 嵌套在哪里?

JPA的模式:从实体生成数据传输对象DTO并将DTO合并到数据库

从实体到 DTO 的转换

如何将数据从 DTO 映射到导航属性?

将验证属性从域实体映射到 DTO