如何使用AutoMapper深度克隆包含IList属性的对象

我正在尝试使用AutoMapper深度克隆以下类:

public class MainData { public MainData() { Details = new List(); } public int Id { get; private set; } public DateTime LastUpdate { get; private set; } public IList 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().ForMember(d => d.Id, o => o.Ignore()); // Mapper.CreateMap().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().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这些对象,所以不确定Serializable解决方案是否会这样做。

UPDATE2:修改了上面的代码来克隆IList。 这似乎工作正常,因为我可以排除使NHibernate认为它已被保存的属性。

这是ValueInjecter的一个解决方案

  var clone = new MainData(); clone.InjectFrom(mainData);//mainData is your source mainData.Details.AsParallel.ForAll(detail => { var dc = new Detail(); dc.InjectFrom(detail); clone.AddDetail(dc); }); 

具有私有设置器的属性不会被设置,(看起来合理)
祝好运 ;)

编辑:我在这里做了一个更好的解决方案

AutoMapper实际上不是克隆API。 我会改用这个克隆技巧:

 public static object CloneObject(object obj) { using (MemoryStream memStream = new MemoryStream()) { BinaryFormatter binaryFormatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Clone)); binaryFormatter.Serialize(memStream, obj); memStream.Seek(0, SeekOrigin.Begin); return binaryFormatter.Deserialize(memStream); } } 

它并不适用于所有情况,但它非常方便。