AutoMapper忽略()问题

3

好的,我希望我没有忽略什么显而易见的问题。以下是我的代码情况。不知何故,尽管我调用了Ignore()方法,SequenceNo属性仍然被映射。我使用的是最新版本。我也在同一项目中测试了两个不同的类,似乎可以工作,那么这种情况出了什么问题呢?

这是领域对象:

 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);

由于我已经设置了 Ignore(),所以 dto.SequenceNo 应该为 0 而非 2。

1个回答

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)有一个构造函数与源(panelID1panelID2sequenceNo)上的多个属性名称完全匹配,因此调用了该构造函数。
另一种禁用此功能的方法是调用DisableConstructorMapping:
Mapper.Configuration.DisableConstructorMapping()

你做得很好!那不是很直观,而且说实话也没有太多意义。为什么它会选择一个无参构造函数?如果有三个或四个重载的构造函数怎么办? - bjhuffine
我不确定——今天下午我会花些时间查看AutoMapper的源代码,看看能否找到答案。 - Andrew Whitaker
@bjhuffine:添加了更多信息,希望有所帮助。在看到你的问题之前我还不知道那个存在! - Andrew Whitaker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接