AutoMapper问题 - 如果DTO包含另一个DTo,则自动执行DTO,Viewmodel

时间:2018-03-26 10:43:33

标签: c# automapper

使用subDto

自动执行dto
class productsDTO
{
    public int id;
    public AddressDTO DeliveryAddress; 
}

Class productsViewModel
{
    public int id;
    public AddressViewModel DeliveryAddress; 
}

在这里,我有一个dto课程。我只是想将dTo类自动映射到视图模型中。在DTO类中,AddressDTo必须在productsViewModel中自动映射AddressViewModel。

如果有人有解决方案,请发布

 var products = [some objects]; 
    products.ForEach(a =>
    { 
    var config = new MapperConfiguration(cfg =>
    { 
    cfg.CreateMap<ProductsDTO, ProductsViewModel>()
    .ForMember(dest => dest.DeliveryAddress, opts =>opts.Ignore())
    .AfterMap((src, dest) => {
    dest.DestinationAddress = 
    Mapper.Map(src.DeliveryAddress,dest.DeliveryAddress);
     }); 
    });
     IMapper iMapper = config.CreateMapper(); 
    var productList = iMapper.Map<ProductsDTO, ProductsViewModel>(a); 
products.add(productList) 
});

此代码产生如下错误:&#34; Mapper未初始化。使用适当的配置调用Initialize。如果您尝试通过容器或其他方式使用映射器实例,请确保您没有对静态Mapper.Map方法的任何调用,并且如果您正在使用ProjectTo或UseAsDataSource扩展方法,请确保传入适当的IConfigurationProvider实例。&#34;

2 个答案:

答案 0 :(得分:0)

首先,您映射AddressDTO和AddressViewModel属性。如果您自动映射相同的属性名称AutoMapper。如果您想要使用不同的名称映射属性,您可以定义哪个属性等于其他...

文件; http://docs.automapper.org/en/stable/Projection.html

在您将映射productsDTO和productsViewModel以及Everythings正常工作之后......:)

答案 1 :(得分:0)

您需要在AddressDTO和AddressViewModel之间添加第二个映射。当您在productsDTO和productsViewModel之间进行映射时,它也会自动映射这些属性,AutoMapper将知道映射应该如何工作。

与映射productsDTO和productsViewModel的方式相同,您也可以映射这些类:

cfg.CreateMap<AddressDTO, AddressViewModel>();

此外,不必像现在这样在循环内多次定义映射。映射只是一个定义,稍后将使用。它只需要指定一次。当您想要实际执行两个对象的映射时,请使用Mapper.Map - 使用此对象的次数。它将使用您事先创建的映射定义。但是cfg.CreateMap只需要为每个类组合调用一次。我也不确定你的代码中是否需要整个“忽略”业务 - 忽略一个属性然后在下一行再次映射它似乎是多余的。您还可以在单​​个Map操作中转换产品列表中的所有对象。

这样的事情会更好,我想:

var config = new MapperConfiguration(cfg =>
{ 
   cfg.CreateMap<ProductsDTO, ProductsViewModel>();
   cfg.CreateMap<AddressDTO, AddressViewModel>();
});
IMapper iMapper = config.CreateMapper(); 

var products = [some objects]; 

List<ProductViewModel> productVMList = iMapper.Map<List<ProductViewModel>>(products);