2011-01-07 74 views
3

我有以下情况:AutoMapper对象映射到目的地子实体收集现有对象

public class Parent : EntityObject 
{ 
    EntityCollection<Child> Children { get; set; } 
} 

public class Child : EntityObject 
{ 
    int Id { get; set; } 
    string Value1 { get; set; } 
    string Value2 { get; set; } 
} 

public class ParentViewModel 
{ 
    List<ChildViewModel> Children { get; set; } 
} 

public class ChildViewModel 
{ 
    int Id { get; set; } 
    string Value1 { get; set; } 
    string Value2 { get; set; } 
} 

Mapper.CreateMap<ParentViewModel, Parent>(); 

Mapper.CreateMap<ChildViewModel, Child>(); 

是否有可能得到AutoMapper到:

  • Map对象在ParentViewModel.Children列表到具有匹配ID的Parent.Children EntityCollection中的对象。
  • Parent.Children中为ParentViewModel.Children中的对象创建新对象,其中在目标列表中找不到来自源的标识的对象。
  • 从源列表中不存在目标标识的Parent.Children中删除对象。

我对这一切都错了吗?

+0

你最终搞清楚如何做到这一点? – JamieGaines 2011-03-07 18:29:57

回答

2

恐怕automapper并不是用来映射到填充对象,它会擦除​​你调用Map()的Parent.Children。 你有几种方法在这里:

  • 一个是创建自己的条件来执行对儿童地图:

    foreach (var childviewmodel in parentviewmodel.Children) 
    { 
        if (!parent.Children.Select(c => c.Id).Contains(childviewmodel.Id)) 
        { 
         parent.Children.Add(Mapper.Map<Child>(childviewmodel)); 
        } 
    } 
    

    其他IFS的其他行为

  • 一种方法是建立一个IMappingAction并将其挂接到BeforeMap方法中:

    class PreventOverridingOnSameIds : IMappingAction<ParentViewModel, Parent> 
    { 
        public void Process (ParentViewModel source, Parent destination) 
        { 
         var matching_ids = source.Children.Select(c => c.Id).Intersect(destination.Children.Select(d => d.Id)); 
         foreach (var id in matching_ids) 
         { 
          source.Children = source.Children.Where(c => c.Id != id).ToList(); 
         } 
        } 
    } 
    

    ..以及后来的

    Mapper.CreateMap<ParentViewModel, Parent>() 
        .BeforeMap<PreventOverridingOnSameIds>(); 
    

    这样你让automapper做这项工作。

+1

感谢您的这项工作,非常有用!然而,通过重新思考架构你是什么意思,你会提出什么样的替代方案?我印象中使用DTOs是一种很好的做法,尤其是对于管理诸如REST API之类的东西。 – 2015-10-22 05:41:26