2017-08-08 715 views
1

假设我有2类:AutoMapper - 忽略特定命名的属性包括子属性

Employee() 
{ 
    int ID; 
    string Name; 
} 

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

鉴于2相似(但不等于)公司的对象,我想一个内容映射到其他映射所有字段除ID(Company.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设置为零!即使当existingCompany和changedCompany上的员工属性都有ID时,它仍然会将包含“ID”的任何字段名称设置为零。所有其他属性都被适当映射。

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

(AutoMapper V3.3.1)

+0

我从来没有使用过AutoMapper,但是你的函数只是循环遍历sourceType的属性。要忽略子元素,我想你还需要遍历子元素。 – Cory

+0

在最新版本中,您将使用全局忽略。 –

+0

事情是孩子的元素仍然受到影响 - 只是没有以预期的方式(他们正在变为零而不是忽略)。第二个CreateMap被调用时,员工属性会循环。 – FBryant87

回答

1

假设你想用列表,以便将员工列表映射(他们有相同数量的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]); 
} 
+0

谢谢 - 有大量的孩子来映射哪个是问题,我可能会试着想出一个类似的方法来遍历所有的属性并遍历它们。 – FBryant87