2011-11-08 29 views
16

Nó không phải là quá nhiều câu hỏi, vì tôi đã tìm được cách để làm những gì tôi muốn, nhưng có vẻ như có cách tốt hơn để làm điều đó. Tôi đã tìm kiếm khắp mọi nơi và không tìm thấy gì cả.Lập bản đồ bộ sưu tập con chỉ đọc với AutoMapper

Về cơ bản, tôi có những gì tôi xem là một mô hình đối tượng rất chuẩn.

public class Parent 
{ 
    private readonly IList<Child> _children = new List<Child>(); 
    public IEnumerable<Child> Children { get { return _children; } } 
    public void AddChild(Child child) 
    { 
     child.Parent = this; 
     _children.Add(child); 
    } 
} 

public class Child 
{ 
    public Parent Parent { get; set; } 
} 

(Tôi đã bỏ qua tính không liên quan đến các vấn đề và lỗi kiểm tra và bảo vệ vì lợi ích của sự rõ ràng ...)

public class ParentDTO 
{ 
    List<ChildDTO> Children = new List<ChildDTO>(); 
} 

public class ChildDTO 
{ 
} 

Lý do tôi sử dụng phương pháp để thêm trẻ em vào bộ sưu tập là duy trì quyền kiểm soát logic nghiệp vụ cần được xử lý khi một đứa trẻ được thêm vào.

Với các bản đồ tiêu chuẩn:

Mapper.CreateMap<Parent, ParentDTO>(); 
Mapper.CreateMap<ParentDTO, Parent>(); 
Mapper.CreateMap<Child, ChildDTO>(); 
Mapper.CreateMap<ChildDTO, Child>(); 

Có vẻ như để làm việc tốt đến từ các lớp dịch vụ. Các con của đối tượng miền ánh xạ hoàn hảo vào danh sách các trường hợp ChildDTO.

Tuy nhiên, khi ánh xạ ngược lại theo cách khác, bộ sưu tập trên mô hình miền không được đặt - bởi vì nó chỉ đọc, rõ ràng. Dường như không có cách nào để trực tiếp thiết lập trường riêng bằng cách sử dụng AutoMapper. Tôi đã thử các đề xuất khác nhau được tìm thấy ở đây và các phần khác của Internet.

Cuối cùng, tôi đã đưa ra các bản đồ sau:

Mapper.CreateMap<ParentDTO, Parent>() 
    .ForMember(m => m.Children, o => o.Ignore()) 
    .AfterMap((s, d) => 
         { 
          foreach(var c in s.Children) 
           d.AddChild(Mapper.Map<ChildDTO, Child>(c)); 
         }); 

này hoạt động như tôi yêu cầu. Tuy nhiên, tôi không thể không cảm thấy rằng phải có một cách tốt hơn, và tôi chưa thử nghiệm điều này với một phụ huynh hiện có đã sửa đổi trẻ em và có thể được thêm vào và bị loại bỏ, vì vậy tôi biết nó chưa thực sự chính xác. Cuối cùng, mô hình miền này được tiếp tục sử dụng NHibernate, vì vậy tôi phải lo lắng về điều đó. Nhưng, một điều tại một thời điểm. :)

Hy vọng điều này có thể giúp người khác gặp phải sự cố tương tự và có thể ai đó đã giải quyết vấn đề đó đúng cách sẽ có thể sửa tôi.

+2

+1 giải pháp sau khi lưu của bạn đã lưu tôi. –

+0

Giải pháp lạnh. Tôi sẽ mượn nó :-) – LeftyX

+0

Ý tưởng tuyệt vời với AfterMap. Nó dễ dàng hơn nhiều để làm việc với các đối tượng Source và Destination so với ResolutionResult và các công cụ như thế! – Andrei

Trả lời

0

Tôi nghĩ nếu bạn định bảo vệ tài sản vì lý do logic kinh doanh tốt thì sẽ rất tệ nếu AutoMapper phá vỡ chúng khi thực hiện ánh xạ. Trong những tình huống như thế này tôi thích từ bỏ cú pháp thông thạo và đặt logic sáng tạo trong phương pháp riêng của mình như thế này:

private Parent MapParentDTOToParent(ParentDTO source) 
{ 
    var parent = new Parent(); 
    // Business logic here 
    return parent 
} 

và sau đó:

Mapper.CreateMap<ParentDTO, Parent>().ConvertUsing(MapParentDTOToParent); 

tôi thấy dễ dàng hơn này đi theo vì phải rất nhiều bỏ qua các khai báo.

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