2016-01-20 94 views
3

我想映射具有子对象集合的同一类型的对象,并且发现忽略()应用于子对象上的属性似乎是umm ...忽略!AutoMapper忽略子集合属性

下面是一个演示问题的单元测试。

class A 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public ICollection<B> Children { get; set; } 
} 

class B 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

[TestClass] 
public class UnitTest1 
{ 
    [TestInitialize()] 
    public void Initialize() 
    { 
     Mapper.CreateMap<A, A>() 
      .ForMember(dest => dest.Id, opt => opt.Ignore()); 

     Mapper.CreateMap<B, B>() 
      .ForMember(dest => dest.Id, opt => opt.Ignore()); 
    } 

    [TestMethod] 
    public void TestMethod1() 
    { 
     A src = new A { Id = 0, Name = "Source", Children = new List<B> { new B { Id = 0, Name = "Child Src" } } }; 
     A dest = new A { Id = 1, Name = "Dest", Children = new List<B> { new B { Id = 11, Name = "Child Dest" } } }; 

     Mapper.Map(src, dest); 

    } 

地图后调用一个对象的ID属性仍然是1,符合市场预期,但小孩B对象的ID属性从11更改为0。

为什么?

回答

6

AutoMapper 4.1.1中有几个bug。

,第一是关于UseDestinationValuehttps://github.com/AutoMapper/AutoMapper/issues/568

第二个是关于嵌套集合:https://github.com/AutoMapper/AutoMapper/issues/934

可怕!解决方法是将您的B情况下,直接映射:

Mapper.CreateMap<A, A>() 
    .ForMember(dest => dest.Id, opt => opt.Ignore()) 
    .ForMember(dest => dest.Children, opt => opt.Ignore()); 

Mapper.CreateMap<B, B>() 
    .ForMember(dest => dest.Id, opt => opt.Condition((ResolutionContext src) => false)); 

,并添加额外的映射电话:

for (int i = 0; i < src.Children.Count; i++) 
{ 
    var srcChild = src.Children[i]; 
    var destChild = dest.Children[i]; 

    Mapper.Map(srcChild, destChild); 
} 

这将弄好的工作:

Mapper.Map(src, dest); 
Mapper.Map(src.Children.First(), dest.Children.First()); //example!!! 

您可以在循环调用Mapper.Map