自动映射器映射覆盖嵌套子实体属性

本文关键字:映射 实体 嵌套 属性 覆盖 | 更新日期: 2023-09-27 18:14:16

我刚开始使用Automapper,并被嵌套子实体的一个特定行为所阻塞。

当更新父对象的子对象时,Automapper正在用使用目标数据创建的新实例替换目标对象中的子对象,而不是逐个复制属性。为了更好地解释这个问题,我复制了下面的测试代码:

class Program
{
    static void Main(string[] args)
    {
        Mapper.CreateMap<PersonDTO, Person>();
        Mapper.CreateMap<UserLoginDTO, UserLogin>();
        Person pmodel = new Person()
        {
            Id = 10,
            FullName = "XYZ",
            LoginInfo = new UserLogin() { Id = 10, UserName = "xyz" }
        };
        PersonDTO pdto = new PersonDTO()
        {
            Id = 10,
            FullName = "XYZ",
            LoginInfo = new UserLoginDTO() { Id = 10, UserName = "abc" }
        };
        pmodel.Initiated();
        pmodel.LoginInfo.Initiated();
        Console.WriteLine("model => LoginInfo => IsInitiated : {0}", pmodel.LoginInfo.IsInitiated);
        Mapper.Map<PersonDTO, Person>(pdto, pmodel);
        Console.WriteLine("model => LoginInfo => IsInitiated : {0}", pmodel.LoginInfo.IsInitiated);
    }
}
public class PersonDTO
{
    public int Id
    {
        get;
        set;
    }
    public String FullName
    {
        get;
        set;
    }

    public UserLoginDTO LoginInfo { get; set; }
}
public class UserLoginDTO
{
    public int Id
    {
        get;
        set;
    }
    public String UserName
    {
        get;
        set;
    }
}
public class Person : BaseEntity
{
    private int _id;
    private string _name;
    private UserLogin _loginInfo;
    public int Id { 
        get { return _id;  }
        set { _id= value; }
    }
    public String FullName
    {
        get { return _name; }
        set { _name = value; }
    }
    public UserLogin LoginInfo { get { return _loginInfo; } set { _loginInfo = value; } }
}
public class UserLogin : BaseEntity
{
    private int _id;
    private string _userName;
    public int Id
    {
        get { return _id; }
        set { _id = value; }
    }
    public String UserName
    {
        get { return _userName; }
        set { _userName= value; }
    }
}

public abstract class BaseEntity
{
    private bool _isInitiated = false;
    public bool IsInitiated { get { return _isInitiated; } }
    public void Initiated()
    {
        this._isInitiated = true;
    }
}

以上代码的输出为:

映射前:model => LoginInfo => IsInitiated: True映射后:model => LoginInfo => IsInitiated: False

我的要求是在映射后保留IsInitiated属性。

自动映射器映射覆盖嵌套子实体属性

我也有同样的问题。我最终使用了该映射方法的返回值。

var result = Mapper.Map<PersonDTO, Person>(pdto, pmodel);

,并为不想覆盖的属性添加了显式忽略。

  Mapper.CreateMap<PersonDTO, Person>()
.ForMember(d => d.IsInitiated, op => op.Ignore());