如何使用 AutoMapper 深度克隆包含 IList 属性的对象
我正在尝试使用 AutoMapper 深度克隆以下类:
public class MainData
{
public MainData()
{
Details = new List<Detail>();
}
public int Id { get; private set; }
public DateTime LastUpdate { get; private set; }
public IList<Detail> Details { get; private set; }
public int Prop1 { get; set; }
public int Prop2 { get; set; }
public void AddDetail(Detail detail)
{
Details.Add(detail);
}
public void RemoveDetail(Detail detail)
{
Details.Remove(detail);
}
public MainData Clone()
{
Mapper.Reset();
Mapper.CreateMap<MainData, MainData>().ForMember(d => d.Id, o => o.Ignore());
// Mapper.CreateMap<Detail, Detail>().ForMember(d => d.Id, o => o.Ignore()); // REMOVED
var newMainData = new MainData();
Mapper.Map(this, newMainData);
newMainData.Details = this.Details.Select(item => item.Clone()).ToList(); // ADDED
return newMainData;
}
}
public class Detail
{
public int Id { get; private set; }
public string Name { get; set; }
public double Area { get; set; }
public double Height { get; set; }
public Detail Clone() // ADDED
{
Mapper.CreateMap<Detail, Detail>().ForMember(d => d.Id, o => o.Ignore());
var newDetail = new Detail();
Mapper.Map(this, newDetail);
return newDetail;
}
}
Clone
方法对于 MainData 属性工作正常,但似乎只对详细信息列表进行浅表复制。我尝试添加 .ForMember(d => d.Details, o => o.UseDestinationValue())
但这根本不会复制详细信息列表。如何获得详细信息列表深度克隆,即,我最终得到两个完全独立的对象,包括所有列表项?
更新: 我需要排除 Id 属性,因为我将这些对象与 NHibernate 一起使用,因此不确定 Serialized 解决方案是否会执行此操作。
更新2:修改了上面的代码以克隆IList。这似乎工作正常,因为我可以排除使 NHibernate 认为它已经被保存的属性。
I am trying to deep clone the following class using AutoMapper:
public class MainData
{
public MainData()
{
Details = new List<Detail>();
}
public int Id { get; private set; }
public DateTime LastUpdate { get; private set; }
public IList<Detail> Details { get; private set; }
public int Prop1 { get; set; }
public int Prop2 { get; set; }
public void AddDetail(Detail detail)
{
Details.Add(detail);
}
public void RemoveDetail(Detail detail)
{
Details.Remove(detail);
}
public MainData Clone()
{
Mapper.Reset();
Mapper.CreateMap<MainData, MainData>().ForMember(d => d.Id, o => o.Ignore());
// Mapper.CreateMap<Detail, Detail>().ForMember(d => d.Id, o => o.Ignore()); // REMOVED
var newMainData = new MainData();
Mapper.Map(this, newMainData);
newMainData.Details = this.Details.Select(item => item.Clone()).ToList(); // ADDED
return newMainData;
}
}
public class Detail
{
public int Id { get; private set; }
public string Name { get; set; }
public double Area { get; set; }
public double Height { get; set; }
public Detail Clone() // ADDED
{
Mapper.CreateMap<Detail, Detail>().ForMember(d => d.Id, o => o.Ignore());
var newDetail = new Detail();
Mapper.Map(this, newDetail);
return newDetail;
}
}
The Clone
method works fine for the MainData properties but seems to only do a shallow copy of the Details list. I have tried adding .ForMember(d => d.Details, o => o.UseDestinationValue())
but this does not copy the Details list at all. How can I get the Details list deep cloned as well ie, so I end up with two totally independent objects including all the list items?
UPDATE: I need to exclude the Id property as I am using these objects with NHibernate so not sure if the Serializable solution will do this.
UPDATE2: Modified the above code to clone the IList too. This seems to work fine as I can exclude properties that make NHibernate think it has already been saved.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是一种使用 ValueInjecter 的解决方案,
不会设置具有私有设置器的属性,(看起来合理)
祝你好运;)
编辑:
我做了一个更好的解决方案,请看这里
here is one solution with the ValueInjecter
the properties that have private setters are not going to be set, (looks reasonable)
good luck ;)
EDIT:
I did a better solution look here
AutoMapper 并不是真正的克隆 API。相反,我会使用这个克隆技巧:
它并不适用于所有情况,但它非常方便。
AutoMapper isn't really a cloning API. I would instead use this cloning trick:
It doesn't work for every situation, but it's pretty handy.