Reputation: 4595
Suppose I have 2 classes:
Employee()
{
int ID;
string Name;
}
Company()
{
int ID;
string Name;
List<Employee> Employees;
}
Given 2 similar (but not equal) Company objects, I want to map the contents of one into the other, mapping all fields except for the IDs (Company.ID and Employee.ID).
I added an Automapper extension to handle this:
public static IMappingExpression<TSource, TDestination> IgnoreIDs<TSource, TDestination>(
this IMappingExpression<TSource, TDestination> expression)
{
var sourceType = typeof(TSource);
foreach (var property in sourceType.GetProperties())
{
if (property.Name.Contains("ID"))
expression.ForMember(property.Name, opt => opt.Ignore());
}
return expression;
}
I call it like so:
Mapper.CreateMap<Company, Company>().IgnoreIDs();
Mapper.CreateMap<Employee, Employee>().IgnoreIDs();
var mappedCompany = Mapper.Map(changedCompany, existingCompany);
This works for all ID properties at Company level (mappedCompany.ID == existingCompany.ID, it ignores changedCompany.ID as expected whilst the other properties change).
But this approach doesn't work for child properties. It always sets any Employee.ID to zero! Even when employee properties on existingCompany and changedCompany both have IDs, it will still set any field name containing "ID" to zero. All other properties are mapped appropriately.
Why is it doing this? It's neither ignoring the property or mapping it, but setting it to default?
(AutoMapper v3.3.1)
Upvotes: 1
Views: 1340
Reputation: 1753
Assuming you want to map the Employee lists using the List order (and they have the same number of ietms) then I think you can do the following
Mapper.CreateMap<Company, Company>().ForMember(dest => dest.Employees,
opts => opts.Ignore()).IgnoreIDs();
Mapper.CreateMap<Employee, Employee>().IgnoreIDs();
var mappedCompany = Mapper.Map(changedCompany, existingCompany);
for (int i = 0; i < existingCompany.Employees.Count; i++)
{
AutoMapper.Mapper.Map(existingCompany.Employees[i], changedCompany.Employees[i]);
}
Upvotes: 1