如何使用 Automapper 将对象列表映射到 DataTable?

问题描述 投票:0回答:1

这是我当前的代码。

public class IncidentMapDatatableProfile : Profile
{
    public IncidentMapDatatableProfile()
    {
        CreateMap<FlattenedIncident, DataRow>();
    }
}

public static class AutoMapperConfig
{
    public static MapperConfiguration ConfigureMappings()
    {
        return new MapperConfiguration(cfg =>
        {     
            cfg.AddProfile<IncidentMapDatatableProfile>();
        });
    }
}

但是当我运行下面的第三行时,我收到此错误 - “AutoMapper.AutoMapperMappingException:'缺少类型映射配置或不受支持的映射。'”。

var mapperConfig = AutoMapperConfig.ConfigureMappings();
IMapper mapper = mapperConfig.CreateMapper();

var incidentsDatatable = mapper.Map<DataTable>(flattenedIncidents);

看起来可能是因为对象映射到 DataRow,后面的对象会映射到 DataTable 吗?

c# automapper
1个回答
0
投票

我不认为 AutoMapper 提供将源映射到目的地

DataTable
DataRow
类型的功能。

您应该实现将

List<T>
转换为
DataTable
的函数。如果你能够实现它,我认为在这种情况下没有必要使用 AutoMapper。

综上所述,需要通过反射从对象中获取属性,并将属性名和值添加到DataRow中。

using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

public static class IEnumerableExtensions
{
    public static DataTable ToDataTable<T>(this IEnumerable<T> source)
        where T : class, new()
    {
        DataTable dt = new DataTable();
        
        if (source == null || !source.Any())
            return dt;
        
        PropertyInfo[] propInfos = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
        
        foreach (var propInfo in propInfos)
        {
            dt.Columns.Add(propInfo.Name, Nullable.GetUnderlyingType(propInfo.PropertyType) ?? propInfo.PropertyType);  
        }
        
        foreach (var item in source)
        {
            DataRow row = dt.NewRow();
            
            foreach (var propInfo in propInfos)
            {
                row[propInfo.Name] = propInfo.GetValue(item);   
            }
            
            dt.Rows.Add(row);
        }
        
        return dt;
    }
}

如果您仍在寻找 AutoMapper 解决方案,您需要实现 自定义类型解析器

数据表转换器:

public class ToDataTableConverter<T> : ITypeConverter<List<T>, DataTable>
    where T : class, new()
{
    public DataTable Convert(List<T> source, DataTable destination, ResolutionContext context)
    {       
        return source.ToDataTable();
    }
}

映射规则:

CreateMap<List<FlattenedIncident>, DataTable>()
            .ConvertUsing(new ToDataTableConverter<FlattenedIncident>());

来电者:

var incidentsDatatable = mapper.Map<DataTable>(flattenedIncidents);

// Or
//var incidentsDatatable = flattenedIncidents.ToDataTable();
© www.soinside.com 2019 - 2024. All rights reserved.