Automapper将2个类配置为一个

时间:2017-09-25 17:15:16

标签: c# automapper automapper-6

我有以下DB(基础结构)类:

[Table("ApplicationDriverEquipments")]
public partial class ApplicationDriverEquipment
{
    public int Id { get; set; }
    [StringLength(256)]
    public string Make { get; set; }
    [StringLength(256)]
    public string Model { get; set; }
    [StringLength(256)]
    public string Year { get; set; }
    [StringLength(256)]
    public string VINNumber { get; set; }
    [StringLength(256)]
    public string PlateNumber { get; set; }
    [StringLength(256)]
    public string CurrentMileage { get; set; }
    [StringLength(256)]
    public string Length { get; set; }


    public int TypeId { get; set; }
    public virtual ApplicationDriverEquipmentType Type { get; set; }

    public int DriverId { get; set; }
    public virtual ApplicationDriver Driver { get; set; }
}

[Table("ApplicationDriverEquipmentTypes")]
public partial class ApplicationDriverEquipmentType
{
    public ApplicationDriverEquipmentType()
    {
        Equipments = new HashSet<ApplicationDriverEquipment>();
    }

    public int Id { get; set; }
    [Required]
    [StringLength(256)]
    public string Name { get; set; }
    public virtual ICollection<ApplicationDriverEquipment> Equipments { get; set; }
}

以及以下DTO(域)类:

public abstract class ApplicationDriverEquipmentAbstractDomain
{
    public int Id { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
    public string Year { get; set; }
    public string PlateNumber { get; set; }
    public string CurrentMileage { get; set; }
    public string Type { get; protected set; }
}

public class ApplicationDriverEquipmentTractorDomain : ApplicationDriverEquipmentAbstractDomain
{
    public ApplicationDriverEquipmentTractorDomain()
    {
        Type = ApplicationDriverEquipmentTypeStaticStringsDomain.Tractor;
    }
    public string VINNumber { get; set; }
}

public class ApplicationDriverEquipmentTrailerDomain : ApplicationDriverEquipmentAbstractDomain
{
    public ApplicationDriverEquipmentTrailerDomain()
    {
        Type = ApplicationDriverEquipmentTypeStaticStringsDomain.Trailer;
    }

    public string Length { get; set; }
}

public class ApplicationDriverEquipmentStraightTruckDomain : ApplicationDriverEquipmentAbstractDomain
{
    public ApplicationDriverEquipmentStraightTruckDomain()
    {
        Type = ApplicationDriverEquipmentTypeStaticStringsDomain.StraightTruck;
    }

    public string VINNumber { get; set; }
    public string Length { get; set; }
}

public class ApplicationDriverEquipmentCargoVanDomain : ApplicationDriverEquipmentAbstractDomain
{
    public ApplicationDriverEquipmentCargoVanDomain()
    {
        Type = ApplicationDriverEquipmentTypeStaticStringsDomain.CargoVan;
    }

    public string VINNumber { get; set; }
    public string Length { get; set; }
}

public static class ApplicationDriverEquipmentTypeStaticStringsDomain
{
    public const string Tractor = "Tractor";
    public const string Trailer = "Trailer";
    public const string StraightTruck = "Straight Truck";
    public const string CargoVan = "Cargo Van";
}

我编写了以下Automapper规则来解决它:

        CreateMap<Domain.POCO.Application.ApplicationDriverEquipmentTractorDomain, Infrastructure.Asset.ApplicationDriverEquipment>()
            .ForMember(c => c.Type.Name, p => p.UseValue<string>(Domain.StaticStrings.ApplicationDriverEquipmentTypeStaticStringsDomain.Tractor));
        CreateMap<Domain.POCO.Application.ApplicationDriverEquipmentTrailerDomain, Infrastructure.Asset.ApplicationDriverEquipment>()
            .ForMember(c => c.Type.Name, p => p.UseValue<string>(Domain.StaticStrings.ApplicationDriverEquipmentTypeStaticStringsDomain.Trailer));
        CreateMap<Domain.POCO.Application.ApplicationDriverEquipmentStraightTruckDomain, Infrastructure.Asset.ApplicationDriverEquipment>()
            .ForMember(c => c.Type.Name, p => p.UseValue<string>(Domain.StaticStrings.ApplicationDriverEquipmentTypeStaticStringsDomain.StraightTruck));
        CreateMap<Domain.POCO.Application.ApplicationDriverEquipmentCargoVanDomain, Infrastructure.Asset.ApplicationDriverEquipment>()
            .ForMember(c => c.Type.Name, p => p.UseValue<string>(Domain.StaticStrings.ApplicationDriverEquipmentTypeStaticStringsDomain.CargoVan));

我收到了一个错误:

  

表达式'c =&gt; c.Type.Name'必须解析为顶级成员而不是   任何子对象的属性。在子类型上使用自定义解析程序   或改为使用AfterMap选项。

更新

我重写了地图:

        CreateMap<Domain.POCO.Application.ApplicationDriverEquipmentTractorDomain, Infrastructure.Asset.ApplicationDriverEquipment>()
            .AfterMap((src, dest)=> dest.Type.Name = Domain.StaticStrings.ApplicationDriverEquipmentTypeStaticStringsDomain.Tractor);
        CreateMap<Domain.POCO.Application.ApplicationDriverEquipmentTrailerDomain, Infrastructure.Asset.ApplicationDriverEquipment>()
            .AfterMap((src, dest) => dest.Type.Name = Domain.StaticStrings.ApplicationDriverEquipmentTypeStaticStringsDomain.Trailer);
        CreateMap<Domain.POCO.Application.ApplicationDriverEquipmentStraightTruckDomain, Infrastructure.Asset.ApplicationDriverEquipment>()
            .AfterMap((src, dest) => dest.Type.Name = Domain.StaticStrings.ApplicationDriverEquipmentTypeStaticStringsDomain.StraightTruck);
        CreateMap<Domain.POCO.Application.ApplicationDriverEquipmentCargoVanDomain, Infrastructure.Asset.ApplicationDriverEquipment>()
            .AfterMap((src, dest) => dest.Type.Name = Domain.StaticStrings.ApplicationDriverEquipmentTypeStaticStringsDomain.CargoVan);

但现在我收到了一个错误:

  

类型地图配置:ApplicationDriverEquipmentTractorDomain - &gt;   ApplicationDriverEquipment   Domain.POCO.Application.ApplicationDriverEquipmentTractorDomain - &gt;   Infrastructure.Asset.ApplicationDriverEquipment

     

属性:类型---&gt; AutoMapper.AutoMapperMappingException:缺少   键入地图配置或不支持的映射。

     

映射类型:

     

字符串 - &gt; ApplicationDriverEquipmentType

     

System.String - &gt; Infrastructure.Asset.ApplicationDriverEquipmentType

似乎,我不明白如何正确映射

2 个答案:

答案 0 :(得分:1)

您正试图从中映射 ApplicationDriverEquipmentTractorDomain.Typestring
ApplicationDriverEquipment.TypeApplicationDriverEquipmentType

您的映射配置在哪里?

是否可以将字符串映射到ApplicationDriverEquipmentType
当然,您可以拥有string Name,但是您在哪里获得IdEquipments

我怀疑你不想在每次映射时都创建该类型的新实例,而是需要从某个字典中查找实例,排序为registry pattern

要实现这个想法,您只需要

  1. 从DB
  2. 加载所有ApplicationDriverEquipmentType
  3. 将它们放入字典中(假设名称是唯一的)
  4. 注册custom type convertercustom value resolver,如下所示
  5. 实现此目的的一种方法是使用custom type converter 你可以使用类似的东西   void ConvertUsing(Func<TSource, TDestination> mappingFunction);
    并输入您自己的功能,以便按名称解析ApplicationDriverEquipmentType假设名称是唯一的,如下所示:

    var applicationEquipments = new ApplicationDriverEquipmentTypeRepository().FindAll(); // get all the values somehow from db
    var dictionary = applicationEquipments.ToDictionary(x=>x.Name);
    Func<string, ApplicationDriverEquipmentType> resolver = x=>dictionary[x]; 
    

    另一种方法是使用custom value resolver 基本上,这个想法是相同的 - 预加载对象的地图,只有你“插入”的方式会有所不同

答案 1 :(得分:0)

尝试使用MapFrom方法:

.ForMember(c => c.Type.Name, p => p.MapFrom(s => Domain.StaticStrings.ApplicationDriverEquipmentTypeStaticStringsDomain.Tractor));