AutoMapper - 忽略包含子属性的特定命名属性

时间:2017-08-08 14:09:12

标签: c# automapper

假设我有两个班级:

Employee()
{
    int ID;
    string Name;
}

Company()
{
    int ID;
    string Name;
    List<Employee> Employees;
}

给出2个相似(但不相等)的公司对象,我想将一个内容映射到另一个,映射除 ID和Employee.ID之外的所有字段

我添加了一个Automapper扩展来处理这个问题:

    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;
    }

我称之为:

Mapper.CreateMap<Company, Company>().IgnoreIDs();
Mapper.CreateMap<Employee, Employee>().IgnoreIDs();
var mappedCompany = Mapper.Map(changedCompany, existingCompany);

适用于公司级别的所有ID属性(mappedCompany.ID == existingCompany.ID,它会按预期忽略changedCompany.ID,而其他属性会更改)。

但是这种方法对于子属性不起作用。它总是将任何Employee.ID设置为零!即使现有公司和changedCompany上的员工财产都有ID,它仍然会将包含“ID”的任何字段名称设置为零。所有其他属性都已正确映射。

为什么这样做?它既不会忽略属性或映射它,而是将其设置为默认值?

(AutoMapper v3.3.1)

1 个答案:

答案 0 :(得分:1)

假设您想使用List顺序映射Employee列表(并且它们具有相同数量的ietms),那么我认为您可以执行以下操作

 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]);
 }