Automapper many to many mapping

19,816

With your current code you're trying to map the GoodAndProviderEntity into ProviderDTO.

Mapper.CreateMap<GoodEntity, GoodDTO>()
  .ForMember(dto => dto.providers, opt => opt.MapFrom(x => x.GoodsAndProviders));

What you want to do, is to map ProviderEntity into ProviderDTO, so all you have to do is select the Providers from GoodsAndProviders as a list:

    Mapper.CreateMap<GoodEntity, GoodDTO>()
      .ForMember(dto => dto.providers, opt => opt.MapFrom(x => x.GoodsAndProviders.Select(y => y.Providers).ToList()));
Share:
19,816
Hellaren
Author by

Hellaren

Updated on July 12, 2022

Comments

  • Hellaren
    Hellaren almost 2 years

    Patrick, thanks for advice about correct question!

    EDIT 1:

    I have three table for many to many relationship. Like this: EF data model

    GoodEntity:

    public partial class GoodEntity
    {
        public GoodEntity()
        {
            this.GoodsAndProviders = new HashSet<GoodAndProviderEntity>();
        }
    
        public int id { get; set; }
        public string name { get; set; }
        public string description { get; set; }
        public decimal cost { get; set; }
        public Nullable<decimal> price { get; set; }
    
        public virtual ICollection<GoodAndProviderEntity> GoodsAndProviders { get; set; }
    }
    

    ProviderEntity:

    public partial class ProviderEntity
    {
        public ProviderEntity()
        {
            this.GoodsAndProviders = new HashSet<GoodAndProviderEntity>();
        }
    
        public int id { get; set; }
        public string name { get; set; }
        public string description { get; set; }
        public string address { get; set; }
        public string phone { get; set; }
        public string email { get; set; }
        public string url { get; set; }
        public Nullable<int> rating { get; set; }
    
        public virtual ICollection<GoodAndProviderEntity> GoodsAndProviders { get; set; }
    }
    

    Entity for many-to-many relationship:

    public partial class GoodAndProviderEntity
    {
        public int id { get; set; }
        public int good_id { get; set; }
        public int provider_id { get; set; }
    
        public virtual GoodEntity Goods { get; set; }
        public virtual ProviderEntity Providers { get; set; }
    }
    

    GoodDTO:

    public class GoodDTO
    {
        public int id { get; set; }
        public string name { get; set; }
        public string description { get; set; }
        public decimal cost { get; set; }
        public decimal? price { get; set; }
    
        public IList<ProviderDTO> providers { get; set; }
    }
    

    ProviderDTO:

    public class ProviderDTO
    {
        public int id { get; set; }
        public string name { get; set; }
        public string description { get; set; }
        public string address { get; set; }
        public string phone { get; set; }
        public string email { get; set; }
        public string url { get; set; }
        public int? rating { get; set; }
    }
    

    This is code for creation maps:

    Mapper.CreateMap<ProviderDTO, ProviderEntity>();
    Mapper.CreateMap<ProviderEntity, ProviderDTO>();
    
    Mapper.CreateMap<GoodEntity, GoodDTO>()
          .ForMember(dto => dto.providers, opt => opt.MapFrom(x => x.GoodsAndProviders));
    Mapper.CreateMap<GoodAndProviderEntity, ProviderDTO>();
    

    And it works half. Automapper was mapped "goods" completely and was created list for all providers for this goods. But automapper don`t fill providers. enter image description here

    If I use Mapper.AssertConfigurationIsValid(), then:

    Unmapped members were found. Review the types and members below. Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type ======================================================= ProviderDTO -> ProviderEntity (Destination member list) Core.DTO.ProviderDTO -> DAL.EF.Entities.ProviderEntity (Destination member list) Unmapped properties: GoodsAndProviders ============================================================== GoodAndProviderEntity -> ProviderDTO (Destination member list) DAL.EF.Entities.GoodAndProviderEntity -> Core.DTO.ProviderDTO (Destination member list)

    How to create mapping for many-to-many relationship?

    Regards, Anton

  • TWilly
    TWilly almost 6 years
    If i were to have a many to many join, and also have additional fields information stored in GoodAndProviderEntity, example GoodAndProviderEntity.IsMapped Do you know how AutoMapper could bring that value onto GoodDTO from the middle many to many field?
  • dwp4ge
    dwp4ge about 5 years
    This worked great now how do you go opposite direction (dto to entity) with many to many navigation property?
  • pantonis
    pantonis over 4 years
    @goodies4uall Did you find a way to do the opposite? I am looking for the same thing
  • dwp4ge
    dwp4ge over 4 years
    @pantonis I updated answer to show how to ignore many to many relationships when going the other direction
  • rolandow
    rolandow over 4 years
    I had to remove the .ToList() to make it work. Also I am curious how to do the opposite: how can I map from a DTO to entity where a join entity should be used?
  • Dživo Jelić
    Dživo Jelić over 4 years
    My bad was that i didnt include all of the tables so this would give me list [ null, null] with null values be sure to Include and ThenInclude both tables. Othervise this works like a charm
  • Darós
    Darós over 3 years
    @TWilly Did you find a solution to your question? I'm looking for the awnser too
  • Robin1990
    Robin1990 over 3 years
    @Darós By having additional fields means we will have duplicated composite key for good_id, provider_id. I think GroupBy might come to use. CreateMap<GoodEntity, GoodDTO>().ForMember(dto => dto.providers, opt => opt.MapFrom(x => x.GoodsAndProviders.GroupBy(g => new { g.good_id, g.provider_id }, g => g.Providers).Select(y => y.FirstOrDefault()).ToList()));
  • Endbo
    Endbo about 3 years
    so was there a solution to your question? to go the opposite way (DTO to DomainModel), when you use update or post