如何使用AutoMapper将对象列表映射到DataTable?映射报错求助
解决AutoMapper将对象列表映射到DataTable的问题
问题原因
你当前仅配置了FlattenedIncident到DataRow的映射,但实际调用的是将List<FlattenedIncident>映射到DataTable——AutoMapper没有内置集合到DataTable的默认映射规则,因此抛出类型映射缺失的错误。
解决方案一:自定义类型转换器
实现一个类型转换器,手动处理对象列表到DataTable的完整转换逻辑,包括表结构创建和行数据填充:
public class FlattenedIncidentListToDataTableConverter : ITypeConverter<List<FlattenedIncident>, DataTable> { public DataTable Convert(List<FlattenedIncident> source, DataTable destination, ResolutionContext context) { if (source == null || !source.Any()) return new DataTable(); // 根据FlattenedIncident的属性创建DataTable列 var dataTable = new DataTable(); var properties = typeof(FlattenedIncident).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); foreach (var prop in properties) { // 处理可空类型,获取底层值类型 var columnType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType; dataTable.Columns.Add(prop.Name, columnType); } // 将每个对象转换为DataRow并添加到表中 foreach (var item in source) { var row = dataTable.NewRow(); foreach (var prop in properties) { row[prop.Name] = prop.GetValue(item) ?? DBNull.Value; } dataTable.Rows.Add(row); } return dataTable; } }
然后在映射配置中注册该转换器:
public class IncidentMapDatatableProfile : Profile { public IncidentMapDatatableProfile() { // 注册列表到DataTable的转换器 CreateMap<List<FlattenedIncident>, DataTable>() .ConvertUsing<FlattenedIncidentListToDataTableConverter>(); // 保留原有的单个对象到DataRow的映射(若后续需要单独使用) CreateMap<FlattenedIncident, DataRow>(); } }
解决方案二:复用现有DataRow映射
如果想复用已配置的FlattenedIncident到DataRow映射,可以直接在List到DataTable的映射中调用该规则:
public class IncidentMapDatatableProfile : Profile { public IncidentMapDatatableProfile() { // 保留原有的单个对象到DataRow的映射 CreateMap<FlattenedIncident, DataRow>(); // 配置列表到DataTable的映射逻辑 CreateMap<List<FlattenedIncident>, DataTable>() .ForMember(dest => dest, opt => opt.MapFrom((src, dest, context) => { if (src == null || !src.Any()) return new DataTable(); // 创建DataTable并定义列结构 var dataTable = new DataTable(); var props = typeof(FlattenedIncident).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); foreach (var prop in props) { var columnType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType; dataTable.Columns.Add(prop.Name, columnType); } // 使用已有的映射规则将每个对象转换为DataRow foreach (var item in src) { var row = dataTable.NewRow(); context.Mapper.Map(item, row); dataTable.Rows.Add(row); } return dataTable; })); } }
验证调用
修改配置后,原调用代码即可正常运行:
var mapperConfig = AutoMapperConfig.ConfigureMappings(); IMapper mapper = mapperConfig.CreateMapper(); var incidentsDatatable = mapper.Map<DataTable>(flattenedIncidents);
注意:如果FlattenedIncident包含复杂类型属性,需确保这些属性能转换为DataTable支持的类型,或在映射中单独处理此类属性。
内容的提问来源于stack exchange,提问作者Steve
相关产品推荐
相关产品推荐

