是否可以使用Automapper将多个DTO对象映射到一个视图模型?

时间:2021-11-16 09:46:11

I was wondering if it is possible to map multiple DTO objects to a single ViewModel object using Automapper?

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

Essentially, I have multiple DTO objects and would like to display information from each on a single screen in ASP.NET MVC 2.0. To do so I would like to flatten the DTO objects (or parts of them...) into the Viewmodel and pass said viewmodel to the view. If I had one DTO this would be easy, but I've never seen it being done with multiple. Obviously there are a number of roundabout ways to do this (outside of automapper), but this is the approach that I would like to take if possible.

本质上,我有多个DTO对象,并希望在ASP中的一个屏幕上显示每个对象的信息。净MVC 2.0。为此,我希望将DTO对象(或它们的一部分…)简化到Viewmodel中,并将所述Viewmodel传递给视图。如果我有一个DTO,这很简单,但是我从来没有见过用多重来做。显然,有很多迂回的方法可以实现这一点(在automapper之外),但如果可能的话,我希望采用这种方法。

5 个解决方案

#1


7  

You could create a composite DTO that holds two or more DTO objects and map the composite DTO to the output view model.

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

#2


13  

Check for following link regarding your query

检查以下链接有关您的查询

http://consultingblogs.emc.com/owainwragg/archive/2010/12/22/automapper-mapping-from-multiple-objects.aspx

http://consultingblogs.emc.com/owainwragg/archive/2010/12/22/automapper-mapping-from-multiple-objects.aspx

#3


7  

If you have 2 DTO classes and 1 flattened view model:

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

And you create mappings for both DTOs to view model:

您为两个dto创建视图模型的映射:

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

You can map 1st DTO to the model and then just "append" 2nd DTO:

您可以将第一个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  

You can add a Map override extension method off IMappingEngine that takes a params array. Something like:

您可以在IMappingEngine上添加映射覆盖扩展方法,该方法获取params数组。喜欢的东西:

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

You could then call it like this:

你可以这样称呼它:

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

#5


0  

I just worked this out myself and have a great solution. It is most likely that your two views are actually related somehow in your system (especially if you are using Entity Framework). Check your models and you should see something which displays the relationship, if you don't then just add it. (The virtual)

我自己解决了这个问题,并有了一个很好的解决方案。很可能您的两个视图在您的系统中以某种方式相互关联(特别是如果您正在使用实体框架)。检查你的模型,你会看到一些显示关系的东西,如果你不添加的话。(虚拟)

Your models

你的模型

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

Your 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 looks like this:

Automapper看起来像这样:

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

I'm assuming you are getting your data with LinQ:

我猜你是从LinQ那里得到数据的

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

Viola, everything will work. In your view just access by using model.dto2.PropertyB

中提琴,一切都会工作。在您的视图中,只需使用model.dto . propertyb进行访问

#1


7  

You could create a composite DTO that holds two or more DTO objects and map the composite DTO to the output view model.

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

#2


13  

Check for following link regarding your query

检查以下链接有关您的查询

http://consultingblogs.emc.com/owainwragg/archive/2010/12/22/automapper-mapping-from-multiple-objects.aspx

http://consultingblogs.emc.com/owainwragg/archive/2010/12/22/automapper-mapping-from-multiple-objects.aspx

#3


7  

If you have 2 DTO classes and 1 flattened view model:

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

And you create mappings for both DTOs to view model:

您为两个dto创建视图模型的映射:

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

You can map 1st DTO to the model and then just "append" 2nd DTO:

您可以将第一个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  

You can add a Map override extension method off IMappingEngine that takes a params array. Something like:

您可以在IMappingEngine上添加映射覆盖扩展方法,该方法获取params数组。喜欢的东西:

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

You could then call it like this:

你可以这样称呼它:

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

#5


0  

I just worked this out myself and have a great solution. It is most likely that your two views are actually related somehow in your system (especially if you are using Entity Framework). Check your models and you should see something which displays the relationship, if you don't then just add it. (The virtual)

我自己解决了这个问题,并有了一个很好的解决方案。很可能您的两个视图在您的系统中以某种方式相互关联(特别是如果您正在使用实体框架)。检查你的模型,你会看到一些显示关系的东西,如果你不添加的话。(虚拟)

Your models

你的模型

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

Your 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 looks like this:

Automapper看起来像这样:

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

I'm assuming you are getting your data with LinQ:

我猜你是从LinQ那里得到数据的

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

Viola, everything will work. In your view just access by using model.dto2.PropertyB

中提琴,一切都会工作。在您的视图中,只需使用model.dto . propertyb进行访问