简体   繁体   中英

Why AutoMapper is not Mapping mapping second level navigation property using ProjectTo?

I have this simple class

public class Store {
    public int Id { get; set; }

    //Other properties

    [JsonIgnore]
    public ICollection<Product> Products { get; set; }
}

and my DTO

public class StoreDetails {
    public int Id { get; set; }

    //Other properties

    public ICollection<Product> Products { get; set; }
}

and my Product class:

public class Product {
    public int? Id { get; set; }

    //Other properties

    public ICollection<ProductAttribute> ProductAttributes { get; set; }
}

And my Mapping looks like that:

var storeDetails = await _context.Stores
    .Include(s => s.Products)
    .ThenInclude(p => p.ProductAttributes)
    .ProjectTo<StoreDetails>(new MapperConfiguration(c => c.CreateProfile("TEST", e => {
        e.CreateMap<Store, StoreDetails>();
    })))
    .SingleOrDefaultAsync(p => p.Id == id);

Everything looks fine in the Store object, but in StoreDetails ProductAttributes is null every time.

Why AutoMapper is not Mapping mapping second level navigation property using ProjectTo?

NOTE: I'm using AutoMapper 8.1.1.

I think you should add virtual property to your class something like this

public class Store {
    public int Id { get; set; }

    //Other properties

    [JsonIgnore]
    public virtual ICollection<Product> Products { get; set; }
}

public class StoreDetails {
    public int Id { get; set; }

    //Other properties

    public virtual ICollection<Product> Products { get; set; }
}

Also use Profile to map like this

public class StoreProfile : Profile
{
    public StoreProfile ()
    {
        CreateMap<Store, StoreDetails>(MemberList.None).ReverseMap();
    }
}

Then register in your startup.cs

services.AddAutoMapper();

This is how you map to the profile

private readonly IMapper _mapper;

var storeDetails = await _context.Stores
    .Include(s => s.Products)
    .ThenInclude(p => p.ProductAttributes)
    .Select(
      x => new ViewModel {
        SomeObject = _mapper.Map<Store, StoreDetails>(x)
      } 
    )
    .SingleOrDefaultAsync(p => p.Id == id);

Below is the version i'm using

<PackageReference Include="AutoMapper" Version="8.0.0" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="6.0.0" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM