簡體   English   中英

如何使用AutoMapper將目標對象與源對象中的子對象進行映射?

[英]How to use AutoMapper to map destination object with a child object in the source object?

我有這樣的源和目標對象:

class ProductWithCategories // Source class
{
    public Product Product { get; set; } // Product is an EF entity class
    public IEnumerable<Category> Categories { get; set; }
}

class ProductViewModel // Dest class
{
    public int Id { get; set; }
    // Other properties with the same name as Product class

    public IEnumerable<CategoryViewModel> Categories { get; set; }
}

所以,我需要的是的值映射source.Productdest然后和source.Categoriesdest.Categories AutoMapper有可能嗎?

我試過這個,當它失敗時我並不感到驚訝:

        config.CreateMap<ProductWithCategories, ProductViewModel>()
            .ForMember(q => q, option => option.MapFrom(q => q.Product))
            .ForMember(q => q.Categories, option => option.MapFrom(q => q.Categories));

以下是我收到的例外情況:

[AutoMapperConfigurationException:成員的自定義配置僅支持某個類型的頂級個人成員。]

在與OP討論之后,事實證明他的主要需求是快速將源對象內的子/嵌套對象映射到展平的目標對象。 他不想為目的地的每個屬性編寫映射。

這是實現此目的的一種方法:

  • 定義映射Product - > ProductViewModel用於展平Product的成員
  • 將映射Category定義為CategoryViewModel
  • 定義一個映射ProductWithCategories - > ProductViewModel ,它映射類別,然后在aftermap中映射Product

    config.CreateMap<ProductWithCategories, ProductViewModel>() .ForMember(q => q.Id, option => option.Ignore()) // flattened in AfterMap .ForMember(q => q.Categories, option => option.MapFrom(q => q.Categories)) .AfterMap((src, dst) => Mapper.Map(src.Product, dst));

使用最新版本的AutoMapper,您可以執行以下操作:

config.CreateMap<Product, ProductViewModel>()
      .ForMember(q => q.Categories, option => option.Ignore());

config.CreateMap<ProductWithCategories, ProductViewModel>()
      .ConstructUsing(s => AutoMapper.Mapper.Map<ProductViewModel>(s.Product))
      .ForMember(q => q.Categories, option => option.MapFrom(q => q.Categories))
      .ForAllOtherMembers(o => o.Ignore();

ConstructUsing()用於從源的嵌套子[ren]生成和填充基類。 如果您有多個這樣的嵌套子級,則需要進行多次映射調用,將其中的每一個連續映射到第一次Map()調用生成的實例上。 .ForAllOtherMembers()是相對較新的(如果您沒有它,請獲取更新版本的AutoMapper。)不幸的是,它稍微不安全,就好像您添加了需要映射但忘記更新地圖的目標成員,配置驗證不會抓住它。

你應該喜歡 -

AutoMapper.Mapper.CreateMap<Category, CategoryViewModel>();
AutoMapper.Mapper.CreateMap<ProductWithCategories, ProductViewModel>()
     .ForMember(a => a.Id, b => b.ResolveUsing(c => c.Product != null ? c.Product.MyProperty : 0))
     .ForMember(a => a.Categories, b => b.ResolveUsing(c => c.Categories));

但最好將ProductViewModel (像Id這樣的道具)中的那些屬性包裝在另一個類中。 並創建另一個地圖,使事物以自動播放方式工作。

產生錯誤的違規行是

.ForMember(q => q, option => option.MapFrom(q => q.Product))

錯誤消息很難理解,但這意味着您必須明確聲明目標屬性:

.ForMember(q => q.Id, option => option.MapFrom(q => q.Product.Id))
.ForMember(q => q.OtherProperty, option => option.MapFrom(q => q.Product.OtherProperty))

您還必須定義從CategoryCategoryViewModel的映射

.ForMember(q => q.Categories, option => option.MapFrom(q => q.Categories))

上班:

config.CreateMap<Category, CategoryViewModel>();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM