3

AutoMapperを使用して、2つのドメインオブジェクトを1つのデータ転送オブジェクトに結合したいと考えています。複数のソースを1つの宛先にマージする

ドメインモデル:

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; } 
} 

マッピング:

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

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

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(); 

私は上記のマッピングを試してみてください

次のエラーが表示されます。

タイプマップの設定が欠落しているか、サポートされていないマッピングです。

マッピングタイプ:EntityQueryable 1 -> PreferenceVM Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable 1 [[Fwims.Core.Data.Model.Setting.Service、 Fwims.Core.Data.Model、バージョン= 1.0.1.10、文化=中立、 なPublicKeyToken = nullを]] - > Fwims.Core.ViewModel.Setting.PreferenceVM

私のマッピングが間違っているように見えますが、私が試したことはありませんでした。ドメインオブジェクトをデータ転送オブジェクトに正しくマップするにはどうすればよいですか?

答えて

3
ここ

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(); 

あなたはICollection<TSource>からのマッピングを作成します。

しかし、後でIQeryable<TSource>をマップしようとしています。 AutoMapperは基本マッピングを使用して派生クラスをマップできますが、IQueryable<T>ICollection<T>から派生しないため、タイプマップの例外がありません。

解決策は、IQueryable<T>ICollection<T>の共通基本インターフェイス(IEnumerable<T>)からのマッピングを作成することです。

そうで上記を置き換える:

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)); 

と現在の問題が解決されます。

このようなシナリオではReverseMapは機能しませんので、削除しました。このような機能が必要な場合は、手動でマッピングを作成する必要があります(最終的にConvertUsingを使用して宛先メンバーがないため)。

+0

ありがとうございました。 – capiono

関連する問題