c# - 将多个来源合并到一个目的地

标签 c# asp.net-mvc entity-framework automapper entity-framework-core

我想使用 AutoMapper 将 2 个域对象组合成一个数据传输对象。

领域模型:

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

映射:

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

当我尝试上面的映射时:

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

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

我收到以下错误:

Missing type map configuration or unsupported mapping.

Mapping types: EntityQueryable1 -> PreferenceVM Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable1[[Fwims.Core.Data.Model.Setting.Service, Fwims.Core.Data.Model, Version=1.0.1.10, Culture=neutral, PublicKeyToken=null]] -> Fwims.Core.ViewModel.Setting.PreferenceVM

看起来我的映射是错误的,我尝试过的都没有用。如何正确地将域对象映射到数据传输对象?

最佳答案

这里

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> 的一些公共(public)基础接口(interface)创建一个映射和 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 因为没有目标成员)。

关于c# - 将多个来源合并到一个目的地,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43614417/

相关文章:

C# 错误消息 : Cannot Implicitly convert type

c# - 没有虚拟化的 WPF DataGrid 性能

c# - 在 C# 中对表达式字符串进行标记

c# - 如何检测远程机器的操作系统

c# - 在 ASP.NET Core 中获取当前星期几

asp.net-mvc - ASP.NET MVC 是否拒绝使用客户端 MVVM?

asp.net-mvc - 为什么visual studio 2012会在mvc项目中自动使用nuget包?

c# - 有没有办法在更新数据库期间显示输出?

c# - 只有实现 IAsyncEnumerable 的源才能用于 Entity Framework 异步操作

c# - EF延迟加载返回null