Combining multiple sources into one destination

I want to combine 2 domain objects into one data transfer object using AutoMapper.

Domain Model:

public class Service  {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public ICollection<DownloadService> DownloadServices { get; set; } = new HashSet<DownloadService>();
}

public class DownloadService {
    public int Id { get; set; }
    public int PageLimit { get; set; }
    public virtual int ServiceId { get; set; }
    public virtual Service Service { get; set; }
}

public class Volume {
    public override int Id { get; set; }
    public bool IsActive { get; set; }
    public string Path { get; set; }
    public string Description { get; set; }
}

      

DTO:

 public class PreferenceVM {
        public ICollection<VolumeVM> Volumes { get; set; }
        public ICollection<ServiceVM> Services { get; set; }
 }

 public class ServiceVM {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public ICollection<DownloadServiceVM> DownloadServices { get; set; } = new HashSet<DownloadServiceVM>();
 }

public class DownloadServiceVM {
        public int Id { get; set; }
        public int PageLimit { get; set; }
        public int CleaningInterval { get; set; }
}

 public class VolumeVM {
        public int Id { get; set; }
        public bool IsActive { get; set; }
        public string Path { get; set; }
        public string Description { get; set; }
}

      

Mapping:

 cfg.CreateMap<Volume, VolumeVM>().ReverseMap();
 cfg.CreateMap<DownloadService, DownloadServiceVM>().ReverseMap();
 cfg.CreateMap<Service, ServiceVM>()
     .ForMember(d => d.DownloadServices, opt => opt.MapFrom(s => s.DownloadServices))
     .ReverseMap();

 cfg.CreateMap<ICollection<Volume>, PreferenceVM>()
            .ForMember(x => x.Volumes, y => y.MapFrom(src => src)).ReverseMap();
 cfg.CreateMap<ICollection<Service>, PreferenceVM>()
            .ForMember(x => x.Services, y => y.MapFrom(src => src)).ReverseMap();

      

when i try to do the following mapping:

 var services = serviceRepository.GetAll();
 var volumes = volumeRepository.GetAll();

 var entities = mapper.Map<PreferenceVM>(services);
 entities = mapper.Map(volumes, entities);

      

I am getting the following errors:

Missing map type configuration or unsupported mapping.

Collation types: EntityQueryable 1 -> PreferenceVM Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable

1 [[Fwims.Core.Data.Model.Setting.Service, Fwims.Core.Data.Model, Version = 1.0.1.10, Culture = neutral, PublicKeyToken = null]] → Fwims.Core.ViewModel.Setting .PreferenceVM

It looks like my mapping is not correct, nothing I tried worked. How do I correctly map domain objects to data transfer objects?

+3


source to share


1 answer


Here

cfg.CreateMap<ICollection<Volume>, PreferenceVM>()
    .ForMember(x => x.Volumes, y => y.MapFrom(src => src)).ReverseMap();

      

and

cfg.CreateMap<ICollection<Service>, PreferenceVM>()
    .ForMember(x => x.Services, y => y.MapFrom(src => src)).ReverseMap();

      

you create mappings from ICollection<TSource>

.

However, later on, you try to display IQeryable<TSource>

. While AutoMapper can use underlying mapping to map a derived class, IQueryable<T>

it is not inferred from ICollection<T>

, therefore, a missing type error exception.



The solution is to create a mapping from some common base interface IQueryable<T>

and ICollection<T>

that IEnumerable<T>

.

So, replace the above:

cfg.CreateMap<IEnumerable<Volume>, PreferenceVM>()
    .ForMember(x => x.Volumes, y => y.MapFrom(src => src));
cfg.CreateMap<IEnumerable<Service>, PreferenceVM>()
    .ForMember(x => x.Services, y => y.MapFrom(src => src));

      

and the current problem will be resolved.

Please note that ReverseMap

doesn't work in scenarios like this, so I just removed it. If you want this kind of functionality, you have to create these mappings manually (eventually using ConvertUsing

because there is no destination).

+3


source







All Articles