2010-01-24 45 views
18

Tôi đã tự hỏi liệu có thể ánh xạ nhiều đối tượng DTO vào một đối tượng ViewModel duy nhất bằng Automapper không?Có thể ánh xạ nhiều đối tượng DTO tới một ViewModel bằng Automapper không?

Về cơ bản, tôi có nhiều đối tượng DTO và muốn hiển thị thông tin từ mỗi đối tượng trên một màn hình đơn trong ASP.NET MVC 2.0. Để làm như vậy tôi muốn làm phẳng các đối tượng DTO (hoặc một phần của chúng ...) vào ViewModel và chuyển viewmodel đã nói đến khung nhìn. Nếu tôi có một DTO, điều này sẽ dễ dàng, nhưng tôi chưa bao giờ thấy nó được thực hiện với nhiều. Rõ ràng có một số cách vòng xoay để làm điều này (bên ngoài automapper), nhưng đây là cách tiếp cận mà tôi muốn thực hiện nếu có thể.

+0

bạn có thể sử dụng ValueInjecter http://valueinjecter.codeplex.com/documentation – Omu

Trả lời

7

Bạn có thể tạo một DTO tổng hợp chứa hai hoặc nhiều đối tượng DTO và ánh xạ DTO hỗn hợp vào mô hình chế độ xem đầu ra.

+1

Đây là những gì chúng tôi đã làm và tôi thấy nó hoạt động tốt nhất. Đối tượng trình bày tổng hợp đó có xu hướng bắt đầu chứa hành vi, vv liên quan đến các đối tượng hỗn hợp. –

+2

Tôi bắt đầu đi xuống tuyến đường đó nhưng sau đó đã nhận ra rằng nếu phải tự ánh xạ tới một đối tượng hỗn hợp trước khi tôi có thể Map <>(), thì bước bổ sung này là gì? Theo cách tiếp cận này, bạn đảm bảo rằng tất cả ánh xạ đối tượng của bạn được quản lý qua AutoMapper, nhưng sau đó sống với ngoại lệ ánh xạ thủ công đối với vật liệu tổng hợp. Tôi không hoàn toàn phản đối ý tưởng này, chỉ cần nói ... – tbehunin

+0

Đồng ý. Giải pháp vừa được đăng bởi Gordon Nongkynrih trông tao nhã hơn nhiều với tôi. –

13
+0

Mặc dù rất muộn trong chủ đề này ;-), cảm ơn bạn rất nhiều vì liên kết này. Tôi chỉ mới bắt đầu với AutoMapper và sẽ sớm gặp phải vấn đề này! Upvote! :-) –

+0

Cảm ơn bạn. Tôi biết khá muộn của nó trong thread nhưng đã phải đối mặt với cùng một vấn đề gần đây. Tôi nhận ra nó không bao giờ muộn để cập nhật thậm chí thread cũ :) – Bahdeng

+5

Đoán nó đã không được lưu trữ lâu dài ... Không còn có sẵn ... – KDT

4

Bạn có thể thêm một phương pháp khuyến nông override Map tắt IMappingEngine mà phải mất một mảng params. Một cái gì đó như:

public static class AutoMapperExtensions 
{ 
    public static T Map<T>(this IMappingEngine engine, params object[] sources) where T : class 
    { 
     if (sources == null || sources.Length == 0) 
      return default(T); 

     var destinationType = typeof (T); 
     var result = engine.Map(sources[0], sources[0].GetType(), destinationType) as T; 
     for (int i = 1; i < sources.Length; i++) 
     { 
      engine.Map(sources[i], result, sources[i].GetType(), destinationType); 
     } 

     return result; 
    } 
} 

Sau đó, bạn có thể gọi nó như thế này:

var result = Mapper.Engine.Map<MyViewModel>(dto1, dto2, dto3); 
7

Nếu bạn có 2 lớp DTO và 1 dẹt xem mô hình:

public class Dto1 
{ 
    public string Property1 { get; set; } 
} 
public class Dto2 
{ 
    public string Property2 { get; set; } 
} 
public class FlattenedViewModel 
{ 
    public string Property1 { get; set; } 
    public string Property2 { get; set; } 
} 

Và bạn tạo ánh xạ cho cả hai DTO để xem mô hình:

CreateMap<Dto1, FlattenedViewModel>(); 
CreateMap<Dto2, FlattenedViewModel>(); 

Bạn có thể lập bản đồ DTO thứ nhất cho mô hình và sau đó chỉ cần "nối thêm" DTO thứ hai:

var dto1 = new Dto1 { Property1 = "Value1"; } 
var dto2 = new Dto2 { Property2 = "Value2"; } 

var model = Mapper.Map<FlattenedViewModel>(dto1); // map dto1 properties 
Mapper.Map(dto2, model); // append dto2 properties 
0

Tôi vừa làm việc này và có giải pháp tuyệt vời. Rất có thể là hai quan điểm của bạn thực sự liên quan đến một cách nào đó trong hệ thống của bạn (đặc biệt là nếu bạn đang sử dụng Khung thực thể). Kiểm tra các mô hình của bạn và bạn sẽ thấy một cái gì đó hiển thị các mối quan hệ, nếu bạn không sau đó chỉ cần thêm nó. (Các virtual)

mô hình của bạn

public class Dto1 
    { 
     public int id { get; set; } 
     public string Property2 { get; set; } 
     public string Property3 { get; set; } 
     public string Property4 { get; set; } 
     public string Property5 { get; set; } 

     public virtual Dto2 dto2{ get; set; } 

    } 

    public class Dto2 
    { 
     public int id { get; set; } 
     public string PropertyB { get; set; } 
     public string PropertyC { get; set; } 
     public string PropertyD { get; set; } 
     public string PropertyE { get; set; } 
    } 

ViewModels của bạn

public class Dto1ViewModel 
    { 
     public string Property1 { get; set; } 
     public string Property2 { get; set; } 

     public virtual Dto2VMForDto1 dto2{ get; set; } 
    } 

//Special ViewModel just for sliding into the above 
    public class Dto2VMForDto1 
    { 
     public int id { get; set; } 
     public string PropertyB { get; set; } 
     public string PropertyC { get; set; } 
    } 

Automapper trông như thế này:

 cfg.CreateMap< Dto1, Dto1ViewModel>(); 
     cfg.CreateMap< Dto2, Dto2VMForDto1 >(); 

tôi giả sử bạn đang nhận được dữ liệu của bạn với LINQ:

Dto1ViewModel thePageVM = (from entry in context.Dto1 where...).ProjectTo<Dto1ViewModel>(); 

Viola, mọi thứ sẽ hoạt động. Trong chế độ xem của bạn, chỉ cần truy cập bằng cách sử dụng model.dto2.PropertyB

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