【问题标题】:AutoMapper issue- Automap the DTO,Viewmodel if DTO contains another DToAutoMapper 问题 - 如果 DTO 包含另一个 DTo,则自动映射 DTO、Viewmodel
【发布时间】:2018-03-26 10:43:32
【问题描述】:

使用 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) 
});

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

【问题讨论】:

  • 您需要在 AddressDTO 和 AddressViewModel 之间定义第二个映射。然后,当您在 productsDTO 和 productsViewModel 之间进行映射时,它也会自动映射这些属性。
  • 你能用示例代码解释一下吗
  • 您创建了 productsDTO 和 productsViewModel 之间的映射(使用 CreateMap),是吗?因此,对其他两个类执行完全相同的操作。
  • var products = [一些对象]; products.ForEach(a =>{ var config = new MapperConfiguration(cfg =>{ cfg.CreateMap().ForMember(dest => dest.DestinationAddress, opts => opts.Ignore()).AfterMap( (src, dest) => { dest.DestinationAddress = Mapper.Map(src.DestinationAddress, dest.DestinationAddress); }); }); IMapper iMapper = config.CreateMapper(); var productList = iMapper.Map(a); products.add(productList)});
  • 这段代码是否正确。但它会产生错误。你能纠正这个

标签: c# automapper


【解决方案1】:

您需要在 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);

【讨论】:

  • 我试过这样。但它会产生错误“错误映射类型。映射类型:ProductsDTO -> ProductViewModel DTO.Products.ProductsDTO -> ViewModels.ProductViewModel 类型映射配置:ProductsDTO -> ProductViewModel DTO。 Products.ProductsDTO -> ViewModels.ProductViewModel 属性:DestinationAddress"
  • 根据您问题中的上述代码,您没有任何名为 DestinationAddress 的字段
  • 很抱歉是 DeliveryAddress
  • 我在答案中为我的 cmets 添加了一些说明。虽然我应该评论 products.add(productList); 毫无意义 - 你不能将 ProductsViewModel` 类型的对象添加到 ProductDTO 类型的列表中(我认为这是 products 是什么。另外,你为什么要这样做?然后你会有一个列表,其中基本上是对象的副本,但格式不同。不确定你想在那里实现什么。但这不是问题的重点。
  • Products 是一个 DTO 列表。我不想将我的 DTO 列表公开给 View。这就是我将 DTO 转换为 productList.Productlist 我将其定义为视图模型列表
【解决方案2】:

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

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

在您映射 productsDTO 和 productsViewModel 之后,一切工作正常.. :)

【讨论】:

  • 我不想映射每个属性。它会自动映射属性。AddressDTO 和 AddressViewModel 具有相同的属性
  • 我只是在这里添加我的代码。如果正确与否。请告诉我
  • var products = [一些对象]; products.ForEach(a =>{ var config = new MapperConfiguration(cfg =>{ cfg.CreateMap().ForMember(dest => dest.DestinationAddress, opts => opts.Ignore()).AfterMap( (src, dest) => { dest.DestinationAddress = Mapper.Map(src.DestinationAddress, dest.DestinationAddress); }); }); IMapper iMapper = config.CreateMapper(); var productList = iMapper.Map(a); products.add(productList)});
  • 您映射了基类,但该类属性是另一个类。如果您想使用它,您将映射所有子类。 (AddressDTO - AddressViewModel)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-13
  • 1970-01-01
  • 1970-01-01
  • 2019-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多