是否可以使用Automapper将多个DTO对象映射到单个ViewModel?

是否可以使用Automapper将多个DTO对象映射到单个ViewModel?

问题描述:

我想知道是否可以使用Automapper将多个DTO对象映射到单个ViewModel对象?是否可以使用Automapper将多个DTO对象映射到单个ViewModel?

本质上,我有多个DTO对象,并希望在ASP.NET MVC 2.0的单个屏幕上显示来自每个对象的信息。为此,我想将DTO对象(或其中的一部分...)平铺到Viewmodel中,并将所述视图模型传递给视图。如果我有一个DTO,这很容易,但我从来没有看到它与多个。很明显,有很多迂回的方法可以做到这一点(automapper之外),但如果可能的话,这是我想采取的方法。

+0

您可以通过ValueInjecter http://valueinjecter.codeplex.com/documentation – Omu 2010-05-05 18:28:06

您可以创建一个包含两个或多个DTO对象并将复合DTO映射到输出视图模型的复合DTO。

+1

这就是我们所做的,我发现它的效果最好。然后,该复合表示对象倾向于开始包含与复合对象有关的行为等。 – 2010-01-25 13:33:32

+2

我开始沿着这条路线前进,但后来认识到,如果在我可以Map ()之前必须手动映射到一个复合对象,那么给我提供的额外步骤是什么?遵循这种方法,你确保所有的对象映射都是通过AutoMapper进行管理的,但是除了手动映射到组合之外。我并不完全反对这个想法,只是说... – tbehunin 2010-10-19 17:58:49

+0

同意。 Gordon Nongkynrih刚刚发布的解决方案对我来说看起来更加优雅。 – 2012-01-19 08:45:01

+0

虽然在这个线程中很晚,但是非常感谢你的这个链接。我刚开始使用AutoMapper,很快就会遇到这个问题!给予好评! :-) – 2012-01-19 08:41:22

+0

谢谢。我知道它在线程中很晚,但最近面临同样的问题。我意识到它永远不会迟到更新甚至老的线程:) – Bahdeng 2012-01-22 08:18:37

+5

猜猜它没有被存档很长时间...不再可用... – KDT 2015-01-22 06:38:43

可以添加地图覆盖扩展方法关闭IMappingEngine,需要一个参数数组链接。喜欢的东西:

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

然后,您可以这样调用它:

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

如果你有2 DTO类和1扁平视图模型:

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

与您共创两个映射DTOs查看模式:

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

您可以第一个DTO映射到模型,然后就“追加”第二DTO:

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 

我只是工作这一点我自己,有一个很好的解决方案。这很可能是您的两个视图实际上在您的系统中以某种方式相关(特别是如果您使用的是实体框架)。检查你的模型,你应该看到显示关系的东西,如果你没有,那么只需添加它。 (该virtual

你的模型

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

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看起来是这样的:

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

我假设你正在使用LINQ让你的数据:

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

中提琴,一切都会奏效。在您看来,只需通过使用model.dto2.PropertyB