2013-03-04 71 views
1

我有一個基類和各種派生類,我想使用AutoMapper映射到TPH結構中的EF實體。AutoMapper - 通過接口重用映射

例子,讓我們說,我有以下簡單的模型:

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」到「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; } 
} 
+0

你試圖將IHasAntiLockBrakeSytem映射到汽車嗎? – Robert 2013-03-04 17:22:16

+0

不,汽車,卡車和自行車繼承VehicleBase和Car and Truck都實現了IHasAntiLockBrakeSystem。我試圖將VehicleBase映射到Vehicle,而無需考慮Car和Truck映射中的IHasAntiLockBrakeSystem屬性。 – 2013-03-04 17:30:32

+0

你可以發佈你的車輛類,我沒有看到它在EF5 DbContext生成的代碼當前代碼 – Robert 2013-03-04 18:24:33

回答

0

我看不出有什麼直接是你說的「車輛」類,但你可以創建一個映射到類似的特徵,並留下任何你不想要。

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

如果你忽略了特定於其他類和接口的屬性,它將不會嘗試映射它們。