Automapper 一个源多个目的地和派生 类
Automapper one source multiple destinations and derived classes
我正在尝试将一个实体对象映射到不同的视图模型。我有一个基础视图模型和两个从基础派生的视图模型。视图模型是根据它们的类型 属性 在 运行 时间内通过工厂方法创建的。派生视图模型没有单独的实体,源实体具有派生视图模型的所有属性。问题是 Automapper 能够通过工厂方法创建正确的对象,但派生对象中的属性根本没有映射。仅映射基本视图模型的属性。
示例实体:
public class VehicleEntity
{
public int Type { get; set; }
public int LoadCapacity { get; set; }
public TrailerEntity Trailer { get; set; }
}
public class TrailerEntity
{
public int Capacity { get; set; }
}
查看型号:
public class VehicleVM
{
public int Type { get; set; }
}
public class CarVM: VehicleVM
{
public TrailerVM Trailer { get; set; }
}
public class TruckVM : VehicleVM
{
public int LoadCapacity { get; set; }
}
public class TrailerVM
{
public int Capacity { get; set; }
}
public static class VehicleFactory
{
public static VehicleVM GetInstance(int type)
{
switch (type)
{
case 1:
return new CarVM();
case 2:
return new TruckVM();
default:
return new VehicleVM();
}
}
}
最后映射:
List<VehicleEntity> vehicleList = new List<VehicleEntity>();
vehicleList.Add(new VehicleEntity()
{
Type = 1,
LoadCapacity = 0,
Trailer = new TrailerEntity()
{
Capacity = 120
}
});
vehicleList.Add(new VehicleEntity()
{
Type = 2,
LoadCapacity = 8000,
Trailer = null
});
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<VehicleEntity, VehicleVM>()
.ConstructUsing((Func<VehicleEntity, VehicleVM>)(rc => VehicleFactory.GetInstance(rc.Type)))
.Include<VehicleEntity, TruckVM>()
.Include<VehicleEntity, CarVM>();
cfg.CreateMap<VehicleEntity, TruckVM>();
cfg.CreateMap<VehicleEntity, CarVM>();
cfg.CreateMap<TrailerEntity, TrailerVM>();
});
IMapper mapper = config.CreateMapper();
var vehicleVMs = mapper.Map<List<Data.VehicleEntity>, List<VehicleVM>>(vehicleList);
在上面的示例中,只有 Type 属性映射到 CarVM 和 TruckVM 中。其他属性不是......我也尝试过使用 ForMember 方法来映射来自源实体的派生 class 属性,但没有成功。
cfg.CreateMap<VehicleEntity, TruckVM>().ForMember(dst => dst.LoadCapacity, opt => opt.MapFrom(src => src.LoadCapacity));
有可能实现吗?
您可以使用以下配置
var config = new MapperConfiguration(
cfg =>
{
cfg.CreateMap<VehicleEntity, VehicleVM>()
.ConstructUsing(rc => VehicleFactory.GetInstance(rc.Type))
.BeforeMap((s, d, c) => c.Mapper.Map(s, d));
cfg.CreateMap<VehicleEntity, TruckVM>();
cfg.CreateMap<VehicleEntity, CarVM>();
cfg.CreateMap<TrailerEntity, TrailerVM>();
});
在这种情况下 ConstructUsing 根据 Type 属性 创建正确的目标对象,然后在 BeforeMap 将源 VehicleEntity 实例映射到创建的目标对象。您也可以在 AfterMap 方法中完成。
或者您可以在 ConstructUsing
中立即创建目标对象并在其上映射源
var config = new MapperConfiguration(
cfg =>
{
cfg.CreateMap<VehicleEntity, VehicleVM>()
.ConstructUsing((rc, context) => context.Mapper.Map(rc, VehicleFactory.GetInstance(rc.Type)));
cfg.CreateMap<VehicleEntity, TruckVM>();
cfg.CreateMap<VehicleEntity, CarVM>();
cfg.CreateMap<TrailerEntity, TrailerVM>();
});
我正在尝试将一个实体对象映射到不同的视图模型。我有一个基础视图模型和两个从基础派生的视图模型。视图模型是根据它们的类型 属性 在 运行 时间内通过工厂方法创建的。派生视图模型没有单独的实体,源实体具有派生视图模型的所有属性。问题是 Automapper 能够通过工厂方法创建正确的对象,但派生对象中的属性根本没有映射。仅映射基本视图模型的属性。
示例实体:
public class VehicleEntity
{
public int Type { get; set; }
public int LoadCapacity { get; set; }
public TrailerEntity Trailer { get; set; }
}
public class TrailerEntity
{
public int Capacity { get; set; }
}
查看型号:
public class VehicleVM
{
public int Type { get; set; }
}
public class CarVM: VehicleVM
{
public TrailerVM Trailer { get; set; }
}
public class TruckVM : VehicleVM
{
public int LoadCapacity { get; set; }
}
public class TrailerVM
{
public int Capacity { get; set; }
}
public static class VehicleFactory
{
public static VehicleVM GetInstance(int type)
{
switch (type)
{
case 1:
return new CarVM();
case 2:
return new TruckVM();
default:
return new VehicleVM();
}
}
}
最后映射:
List<VehicleEntity> vehicleList = new List<VehicleEntity>();
vehicleList.Add(new VehicleEntity()
{
Type = 1,
LoadCapacity = 0,
Trailer = new TrailerEntity()
{
Capacity = 120
}
});
vehicleList.Add(new VehicleEntity()
{
Type = 2,
LoadCapacity = 8000,
Trailer = null
});
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<VehicleEntity, VehicleVM>()
.ConstructUsing((Func<VehicleEntity, VehicleVM>)(rc => VehicleFactory.GetInstance(rc.Type)))
.Include<VehicleEntity, TruckVM>()
.Include<VehicleEntity, CarVM>();
cfg.CreateMap<VehicleEntity, TruckVM>();
cfg.CreateMap<VehicleEntity, CarVM>();
cfg.CreateMap<TrailerEntity, TrailerVM>();
});
IMapper mapper = config.CreateMapper();
var vehicleVMs = mapper.Map<List<Data.VehicleEntity>, List<VehicleVM>>(vehicleList);
在上面的示例中,只有 Type 属性映射到 CarVM 和 TruckVM 中。其他属性不是......我也尝试过使用 ForMember 方法来映射来自源实体的派生 class 属性,但没有成功。
cfg.CreateMap<VehicleEntity, TruckVM>().ForMember(dst => dst.LoadCapacity, opt => opt.MapFrom(src => src.LoadCapacity));
有可能实现吗?
您可以使用以下配置
var config = new MapperConfiguration(
cfg =>
{
cfg.CreateMap<VehicleEntity, VehicleVM>()
.ConstructUsing(rc => VehicleFactory.GetInstance(rc.Type))
.BeforeMap((s, d, c) => c.Mapper.Map(s, d));
cfg.CreateMap<VehicleEntity, TruckVM>();
cfg.CreateMap<VehicleEntity, CarVM>();
cfg.CreateMap<TrailerEntity, TrailerVM>();
});
在这种情况下 ConstructUsing 根据 Type 属性 创建正确的目标对象,然后在 BeforeMap 将源 VehicleEntity 实例映射到创建的目标对象。您也可以在 AfterMap 方法中完成。
或者您可以在 ConstructUsing
中立即创建目标对象并在其上映射源var config = new MapperConfiguration(
cfg =>
{
cfg.CreateMap<VehicleEntity, VehicleVM>()
.ConstructUsing((rc, context) => context.Mapper.Map(rc, VehicleFactory.GetInstance(rc.Type)));
cfg.CreateMap<VehicleEntity, TruckVM>();
cfg.CreateMap<VehicleEntity, CarVM>();
cfg.CreateMap<TrailerEntity, TrailerVM>();
});