自动映射器映射覆盖嵌套子实体属性
本文关键字:映射 实体 嵌套 属性 覆盖 | 更新日期: 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());