代码之家  ›  专栏  ›  技术社区  ›  JP.

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

  •  18
  • JP.  · 技术社区  · 15 年前

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

    实际上,我有多个DTO对象,并且希望在ASP.NET MVC 2.0中的单个屏幕上显示每个对象的信息。为此,我想将DTO对象(或其中的部分…)展平到视图模型中,并将所述视图模型传递给视图。如果我有一个DTO,这很容易,但我从未见过它是用多个DTO完成的。显然,有很多迂回的方法可以做到这一点(在automapper之外),但如果可能的话,这是我想采用的方法。

    5 回复  |  直到 8 年前
        1
  •  7
  •   Alexander Groß    15 年前

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

        3
  •  7
  •   Nenad    10 年前

    如果有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; }
    }
    

    并为两个DTO创建到视图模型的映射:

    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
    
        4
  •  4
  •   bkaid    12 年前

    您可以在imappingengine中添加一个获取参数数组的map override扩展方法。类似:

    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);
    
        5
  •  0
  •   Worthy7    8 年前

    我自己解决了这个问题,有一个很好的解决方案。很可能您的两个视图实际上在您的系统中以某种方式相关(特别是当您使用实体框架时)。检查你的模型,你应该看到一些显示关系的东西,如果你不这样做,就添加它。(The 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; }
        }
    

    你的视图模型

        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