2014-11-05 143 views
3

好吧,我希望我只是以某种方式忽略明显。我有下面的代码情况。出于某种原因,即使我调用Ignore(),SequenceNo属性仍然得到映射。我正在使用最新版本。我也在同一个项目中使用了两个不同的类来测试它,并且它似乎可行,那么这种情况有什么问题呢?AutoMapper忽略()问题

这是域对象:

public class CableID 
{ 
    private string _panelID1; 
    public string PanelID1 
    { 
     get { return _panelID1; } 
     private set { _panelID1 = value; } 
    } 

    private string _panelID2; 
    public string PanelID2 
    { 
     get { return _panelID2; } 
     private set { _panelID2 = value; } 
    } 

    private int _sequenceNo; 
    public int SequenceNo 
    { 
     get { return _sequenceNo; } 
     private set { _sequenceNo = value; } 
    } 

    private DateTime _inService; 
    public DateTime InService 
    { 
     get { return _inService; } 
     set { _inService = value; } 
    } 

    private string _id; 
    public string ID 
    { 
     get { return _id; } 
     private set { _id = value; } 
    } 

    public CableID(string panelID1, string panelID2, int sequenceNo) 
    { 
     this.PanelID1 = panelID1; 
     this.PanelID2 = panelID2; 
     this.SequenceNo = sequenceNo; 
     this.ID = string.Format("({0}-{1}){2}", this.PanelID1, this.PanelID2, this.SequenceNo); 
    } 

    public CableID(string id) 
    { 
     if (string.IsNullOrEmpty(id)) 
      throw new ArgumentNullException("id"); 

     this.ID = id; 
    } 
} 

这里是DTO对象:

public class CableIDDTO 
{ 
    private string _panelID1; 
    public string PanelID1 
    { 
     get { return _panelID1; } 
     set { _panelID1 = value; } 
    } 

    private string _panelID2; 
    public string PanelID2 
    { 
     get { return _panelID2; } 
     set { _panelID2 = value; } 
    } 

    private int _sequenceNo; 
    public int SequenceNo 
    { 
     get { return _sequenceNo; } 
     set { _sequenceNo = value; } 
    } 

    private string _id; 
    public string ID 
    { 
     get { return _id; } 
     set { _id = value; } 
    } 

    public CableIDDTO() 
    { } 

    public CableIDDTO(string panelID1, string panelID2, int sequenceNo) 
    { 
     this.PanelID2 = panelID1; 
     this.PanelID1 = panelID2; 
     this.SequenceNo = sequenceNo; 
     this.ID = string.Format("({0}-{1}){2}", this.PanelID2, this.PanelID1, this.SequenceNo); 
    } 
} 

最后的AutoMapper用例:

 CableID cableID = new CableID("A1", "B1", 2); 
     Mapper.CreateMap<CableID, CableIDDTO>() 
       .ForMember(dest => dest.SequenceNo, opt => opt.Ignore()); 

     CableIDDTO dto = Mapper.Map<CableID, CableIDDTO>(cableID); 

dto.SequenceNo = 2时,因为我已经设置忽略()它应该是0。

回答

5

这是因为AutoMapper是找到此CableIDDTO构造:

public CableIDDTO(string panelID1, string panelID2, int sequenceNo) 

并调用它,设定sequenceNo。我不确定如何或为什么这样做 - 我会继续挖掘。

你可以通过调用.ConstructUsing并告诉AutoMapper使用无参数的构造函数解决这个问题:

Mapper.CreateMap<CableID, CableIDDTO>() 
    .ConstructUsing((Func<CableID, CableIDDTO>)(src => new CableIDDTO())) 
    .ForMember(dest => dest.SequenceNo, opt => opt.Ignore()); 

经进一步研究,这看起来像在AutoMapper一个特点,尝试匹配了目的地源属性名称构造函数。由于您的目标类型(CableIDDTO)的构造函数与源中的多个属性名称(panelID1,panelID2sequenceNo)完全匹配,因此调用了该构造函数。

另一种方法来禁用此功能是调用DisableConstructorMapping

Mapper.Configuration.DisableConstructorMapping() 
+0

你钉它!这并不直观,诚实也没有多大意义。为什么它在无参数构造函数可用时抓取那个?如果有三个或四个重载的构造函数呢? – bjhuffine 2014-11-05 21:11:22

+0

我不确定 - 我今天下午需要一些时间,并通过AutoMapper的源代码来查看我是否可以找出 – 2014-11-05 21:15:36

+0

@bjhuffine:添加了一些更多信息,希望有所帮助。直到你的问题我都不知道! – 2014-11-05 22:27:12