You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 08:05:31