0

我有以下数据库(基础设施)类:

[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 => 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 -> ApplicationDriverEquipment Domain.POCO.Application.ApplicationDriverEquipmentTractorDomain -> Infrastructure.Asset.ApplicationDriverEquipment

属性:类型 ---> AutoMapper.AutoMapperMappingException:缺少类型映射配置或不支持的映射。

映射类型:

字符串 -> ApplicationDriverEquipmentType

System.String -> Infrastructure.Asset.ApplicationDriverEquipmentType

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

4

2 回答 2

1

您正在尝试映射 from
ApplicationDriverEquipmentTractorDomain.Typeis a string
to
ApplicationDriverEquipment.Typeis aApplicationDriverEquipmentType

您的映射配置在哪里?

甚至可以将字符串映射到 aApplicationDriverEquipmentType吗?
当然,你可以有 a string Name,但是你从哪里得到Idand Equipments

我怀疑您不想在每次映射时都创建该类型的新实例,而是需要从某个字典中查找一个实例,类似于注册表模式

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

  1. ApplicationDriverEquipmentType从数据库加载所有
  2. 将它们放入字典中(假设名称是唯一的)
  3. 注册一个自定义类型转换器自定义值解析器,如下所示

实现这一点的一种方法是使用自定义类型转换器
您可以使用类似
void ConvertUsing(Func<TSource, TDestination> mappingFunction);
And put in your own function that would resolve your ApplicationDriverEquipmentTypename,假设 name 是唯一的,如下所示:

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

另一种方法是使用自定义值解析器
本质上,这个想法是相同的 - 预加载对象的映射,只是你“插入”的方式会有所不同

于 2017-09-25T18:44:52.653 回答
0

尝试改用MapFrom方法:

.ForMember(c => c.Type.Name, p => p.MapFrom(s => Domain.StaticStrings.ApplicationDriverEquipmentTypeStaticStringsDomain.Tractor));
于 2017-09-25T17:48:16.027 回答