This is my current code.
public class IncidentMapDatatableProfile : Profile
{
public IncidentMapDatatableProfile()
{
CreateMap<FlattenedIncident, DataRow>();
}
}
public static class AutoMapperConfig
{
public static MapperConfiguration ConfigureMappings()
{
return new MapperConfiguration(cfg =>
{
cfg.AddProfile<IncidentMapDatatableProfile>();
});
}
}
But when I run this third line below, I got this error:
AutoMapper.AutoMapperMappingException: 'Missing type map configuration or unsupported mapping.'
var mapperConfig = AutoMapperConfig.ConfigureMappings();
IMapper mapper = mapperConfig.CreateMapper();
var incidentsDatatable = mapper.Map<DataTable>(flattenedIncidents);
Looks like it could be due to the object mapping to a DataRow
, will it be able to map to a DataTable
later?
I don't think that AutoMapper provides the feature to map the source to the destination either DataTable
or DataRow
type.
You should implement the function to convert the List<T>
to DataTable
. If you are able to implement it, I don't think there is a need to use AutoMapper in this case.
In summary, the reflection is needed to obtain the properties from the object and add the property name and value into the 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;
}
}
If you are still looking for an AutoMapper solution, you need to implement the Custom Type Resolver.
DataTable Converter:
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();
}
}
Mapping rules:
CreateMap<List<FlattenedIncident>, DataTable>()
.ConvertUsing(new ToDataTableConverter<FlattenedIncident>());
Caller:
var incidentsDatatable = mapper.Map<DataTable>(flattenedIncidents);
// Or
//var incidentsDatatable = flattenedIncidents.ToDataTable();