AutoMapper -通过接口重用映射

本文关键字:映射 接口 -通 AutoMapper | 更新日期: 2023-09-27 18:02:02

我有一个基类和各种派生类,我想使用AutoMapper将它们映射到TPH结构中的EF实体。

示例,假设我有以下简单模型:

public abstract class VehicleBase
{
    public readonly VehicleType VehicleType;
    public readonly int NumWheels;
    protected VehicleBase(VehicleType vehicleType, int numWheels)
    {
        this.VehicleType = vehicleType;
        this.NumWheels = numWheels;
    }
    public int Id { get; set; }
    public int PolicyId { get; set; }
    public int Year { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
}
public class Cycle : VehicleBase
{
    public Cycle()
        : base(VehicleType.Cycle, 2)
    {
    }
    public bool HasJetKit { get; set; }
}
public class Truck : VehicleBase, IHasAntiLockBrakeSystem
{
    public Truck()
        : base(VehicleType.Truck, 4)
    {
    }
    public AntiLockBrakeSystem AntiLockBrakeSystem { get; set; }
    public bool AntiLockBrakeSystemIsStandard { get; set; }
    public bool IsCrewCab { get; set; }
}
public class Car : VehicleBase, IHasAntiLockBrakeSystem
{
    public Car()
        : base(VehicleType.Car, 4)
    {
    }
    public AntiLockBrakeSystem AntiLockBrakeSystem { get; set; }
    public bool AntiLockBrakeSystemIsStandard { get; set; }
    public int NumDoors { get; set; }
}
public class AntiLockBrakeSystem
{
    public int SomeValue { get; set; }
}
public interface IHasAntiLockBrakeSystem
{
    AntiLockBrakeSystem AntiLockBrakeSystem { get; set; }
    bool AntiLockBrakeSystemIsStandard { get; set; }
}
public enum VehicleType
{
    UNDEFINED = 0,
    Car = 1,
    Truck = 2,
    Cycle = 3
}

是否有任何方法可以使用IHasAntiLockBrakeSystem这样的接口,让AutoMapper映射该接口的属性,而不必为实现该接口的每个类映射它们?明白了吗?

我开始了这条路:

AutoMapper.Mapper.CreateMap<DomainModel.VehicleBase, DalModel.Vehicle>()
  .ForMember(dst => dst.VehicleTypeId, opt => opt.MapFrom(src => (byte)src.VehicleType))
  .ForMember(dst => dst.NumWheels, opt => opt.MapFrom(src => (byte)src.NumWheels))
  // include derived mappings
  .Include<DomainModel.Car, DalModel.Vehicle>()
  .Include<DomainModel.Truck, DalModel.Vehicle>()
  .Include<DomainModel.Cycle, DalModel.Vehicle>()
AutoMapper.Mapper.CreateMap<DomainModel.Car, DalModel.Vehicle>()
  .ForMember(dst => dst.NumDoors, opt => opt.MapFrom(src => (byte)src.NumDoors))
  .Include<DomainModel.IHasAntiLockBrakeSystem, DalModel.Vehicle>();
AutoMapper.Mapper.CreateMap<DomainModel.Truck, DalModel.Vehicle>()
  .Include<DomainModel.IHasAntiLockBrakeSystem, DalModel.Vehicle>();
AutoMapper.Mapper.CreateMap<DomainModel.Cycle, DalModel.Vehicle>();

但是我得到一个编译错误尝试与映射:

.Include<DomainModel.IHasAntiLockBrakeSystem, DalModel.Vehicle>();

类型'AutoMapperTesting.DomainModel。IHasAntiLockBrakeSystem'不能用作泛型类型或方法'AutoMapper.IMappingExpression.Include()'中的类型参数'TOtherSource'。没有从"AutoMapperTesting.DomainModel"的隐式引用转换。IHasAntiLockBrakeSystem' to 'AutoMapperTesting.DomainModel.Car'.

EF5生成的实体如下:

    public partial class Vehicle
{
    public int Id { get; set; }
    public int PolicyId { get; set; }
    public byte VehicleTypeId { get; set; }
    public byte NumWheels { get; set; }
    public Nullable<bool> HasJetKit { get; set; }
    public Nullable<bool> IsCrewCab { get; set; }
    public Nullable<byte> NumDoors { get; set; }
    public virtual AntiLockBrakeSystem AntiLockBrakeSystem { get; set; }
    public virtual Policy Policy { get; set; }
    public virtual VehicleType VehicleType { get; set; }
}
public partial class AntiLockBrakeSystem
{
    public int VehicleId { get; set; }
    public int SomeValue { get; set; }
    public bool IsStandard { get; set; }
    public virtual Vehicle Vehicle { get; set; }
}

AutoMapper -通过接口重用映射

我没有看到你所说的"Vehicle"类中直接有什么,但是你可以创建一个类似特征的映射,并省略任何你不想要的。

Mapper.CreateMap<VehicleBase, Vehicle>()
            .ForMember(dest => dest.firstProp, opt => opt.MapFrom(source => source.FirstProp))
            .ForMember(dest => dest.secondProp, opt => opt.MapFrom(source => source.secondProp))

如果您省略了特定于其他类和接口的属性,它将不会尝试映射它们