2017-08-08 713 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