2011-11-08 63 views
16

這不是一個問題,因爲我找到了一種方法來做我想做的事情,但似乎應該有更好的方法來做到這一點。我到處搜索,沒有發現任何東西。使用AutoMapper繪製只讀子集合

基本上,我有我認爲是一個非常標準的對象模型。

public class Parent 
{ 
    private readonly IList<Child> _children = new List<Child>(); 
    public IEnumerable<Child> Children { get { return _children; } } 
    public void AddChild(Child child) 
    { 
     child.Parent = this; 
     _children.Add(child); 
    } 
} 

public class Child 
{ 
    public Parent Parent { get; set; } 
} 

(我省略性質無關的問題和錯誤校驗守着清楚起見...)

public class ParentDTO 
{ 
    List<ChildDTO> Children = new List<ChildDTO>(); 
} 

public class ChildDTO 
{ 
} 

原因我使用的方法來增加孩子的收集是維護需要在添加一個孩子要處理的業務邏輯的控制。

擁有標準映射:

Mapper.CreateMap<Parent, ParentDTO>(); 
Mapper.CreateMap<ParentDTO, Parent>(); 
Mapper.CreateMap<Child, ChildDTO>(); 
Mapper.CreateMap<ChildDTO, Child>(); 

這似乎很好地工作從服務層來了。域對象的子項完全映射到ChildDTO實例的列表。

但是,當以另一種方式反向映射時,域模型上的集合未設置 - 因爲它顯然是隻讀的。似乎沒有任何方法可以使用AutoMapper直接設置專用字段。我嘗試過在這裏和互聯網的其他部分發現的各種建議。

最後,我想出了以下映射:

Mapper.CreateMap<ParentDTO, Parent>() 
    .ForMember(m => m.Children, o => o.Ignore()) 
    .AfterMap((s, d) => 
         { 
          foreach(var c in s.Children) 
           d.AddChild(Mapper.Map<ChildDTO, Child>(c)); 
         }); 

這工作,因爲我需要的。然而,我不禁感到必須有更好的方法,而且我還沒有用一個已經修改過子代並可能添加和刪除的現有父級進行測試,所以我知道它實際上並不正確。最終,這個領域模型是使用NHibernate持久化的,所以我不必擔心這一點。但是,一次只有一件事。 :)

希望這可以幫助別人誰是遇到了同樣的問題,也許有人誰的解決得當就能指正。

+2

+1你的aftermap解決方案救了我。 –

+0

很酷的解決方案。我會借它:-) – LeftyX

+0

用AfterMap的好主意。使用Source和Destination對象比使用ResolutionResult和類似的東西容易得多! – Andrei

回答

0

我認爲,如果你要保護性能良好的業務邏輯的理由那麼這將是壞的,如果AutoMapper做它的映射時避開他們。在這樣的情況下,我寧願放棄流利的語法並把創建邏輯在其自己的方法是這樣的:

private Parent MapParentDTOToParent(ParentDTO source) 
{ 
    var parent = new Parent(); 
    // Business logic here 
    return parent 
} 

然後:

Mapper.CreateMap<ParentDTO, Parent>().ConvertUsing(MapParentDTOToParent); 

我覺得這是容易按照比有很多的忽略聲明。