2010-08-03 28 views
13

Tôi cố gắng để nhân bản sâu lớp sau đây sử dụng AutoMapper:Làm thế nào để đối tượng nhân bản sâu chứa một tài sản IList sử dụng 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; 
    } 
} 

Phương pháp Clone hoạt động tốt cho các thuộc tính MainData nhưng dường như chỉ làm một bản sao cạn của danh sách Chi tiết. Tôi đã thử thêm .ForMember(d => d.Details, o => o.UseDestinationValue()) nhưng điều này không sao chép danh sách chi tiết cả. Làm thế nào tôi có thể nhận được danh sách chi tiết nhân bản sâu cũng như tức là, vì vậy tôi kết thúc với hai đối tượng hoàn toàn độc lập bao gồm tất cả các mục danh sách?

CẬP NHẬT: Tôi cần loại trừ thuộc tính Id vì tôi đang sử dụng các đối tượng này với NHibernate để không chắc chắn nếu giải pháp Serializable có thể thực hiện việc này.

CẬP NHẬT 2: Đã sửa đổi mã ở trên để sao chép IList quá. Điều này dường như làm việc tốt như tôi có thể loại trừ các thuộc tính mà làm cho NHibernate nghĩ rằng nó đã được lưu.

Trả lời

9

đây là một trong những giải pháp với 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); 
     }); 

các thuộc tính có setters tin sẽ không được thiết lập, (trông hợp lý)
may mắn;)

EDIT: tôi đã làm một giải pháp tốt hơn, hãy xem here

+0

Thư viện rất hay, hoạt động tốt. Đã phải thay đổi phần PLINQ thành vòng lặp ForEach vì tôi chưa sử dụng .NET 4. –

+0

@Pier Myers, tôi đã làm một cái gì đó chung chung hơn cho nhân bản, bạn có thể nhìn thấy nó ở đây http://valueinjecter.codeplex.com/wikipage?title=Deep%20Cloning&referringTitle=Home – Omu

+0

cảm ơn cho bản cập nhật, tôi sẽ kiểm tra xem nó ra. –

9

AutoMapper không thực sự là một API nhân bản. Thay vào đó, tôi sẽ sử dụng mẹo nhân bản này:

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

Nó không hoạt động cho mọi tình huống, nhưng nó khá tiện dụng.

+0

cảm ơn, tôi đã xem xét giải pháp này một vài lần trong tìm kiếm của tôi nhưng không chắc chắn tôi muốn làm cho tất cả các lớp của tôi có thể Serializable hay không. Phương pháp Automapper trông khá tao nhã nếu tôi có thể làm cho nó hoạt động như tôi muốn. –

+0

đây là một hack phổ biến cho nhân bản. tiếc là nó giới thiệu tất cả các loại vấn đề đi kèm với serialization/deserialization. Tôi đã hy vọng AutoMapper sẽ thẳng tiến hơn nữa :) –

Các vấn đề liên quan