繁体   English   中英

使用 AutoMapper CreateMap 将属性映射到对象列表

[英]Map a property to list of object using AutoMapper CreateMap

首先,对不起我的英语:)

我正在使用 AutoMapper 在类之间进行映射。

我有如下类的结构。

public class OrderDto {
  int Id { get; set; }
}

public class OrderDtoList {
  OrderDto[] Orders { get; set; }
}

public class Order {
  int Id { get; set; }
}

我的问题是,我想使用 AutoMapping Profile 将 OrderDtoList 对象映射到 List。

public class OrderMappingProfile : Profile {
  public OrderMappingProfile() {
    CreateMap<OrderDto, Order>();
    CreateMap<OrderDtoList, List<Order>(); // <<<<<<<< I cannot figure out this.
  }
}

但是我不知道如何编写 CreateMap<>() 函数。

请帮忙。

从头开始获取它有点困难,但它是可能的。 您必须创建一个ITypeConverter<,>并将其应用于转换。

请注意, ConvertUsing()方法也有一个重载来简单地添加一个内联函数,但是您需要访问映射器本身来调用它以将内部对象映射到所需的结果对象,并且这仅适用于类型转换器接口。

public class OrderMappingProfile : Profile
{
    public OrderMappingProfile()
    {
        CreateMap<OrderDto, Order>();
        CreateMap<OrderDtoList, List<Order>>().ConvertUsing<CustomConverter>();
    }
}

public class CustomConverter : ITypeConverter<OrderDtoList, List<Order>>
{
    public List<Order> Convert(OrderDtoList source, List<Order> destination, ResolutionContext context)
    {
        return context.Mapper.Map<List<Order>>(source.Orders);
    }
}

有了这个,您可以直接从 DTO 创建所需的列表:

public static class Program
{
    public static void Main()
    {
        var config = new MapperConfiguration(cfg => cfg.AddProfile<OrderMappingProfile>());
        var mapper = config.CreateMapper();

        var orderList = new OrderDtoList { Orders = Enumerable.Range(1, 10).Select(i => new OrderDto { Id = i }).ToArray() };
        var orders = mapper.Map<List<Order>>(orderList);
    }
}

正如 Lucian 所提到的, ConvertUsing()一个提供上下文的重载。 所以你也可以内联它,而不是使用自己的类:

// Use lambda method
CreateMap<OrderDtoList, List<Order>>()
    .ConvertUsing((source, _, context) => context.Mapper.Map<List<Order>>(source.Orders));

// Use static method
CreateMap<OrderDtoList, List<Order>>().ConvertUsing(ListConverter);

private static List<Order> ListConverter(OrderDtoList source, List<Order> destination, ResolutionContext context)
{
    return context.Mapper.Map<List<Order>>(source.Orders);
}

您可以创建一个实现 ITypeConverter< OrderDtoList, List > 的类,并使用ConvertUsing方法创建映射。

public class OrderDtoListMapper : ITypeConverter<OrderDtoList, List<Order>>
{
    public List<Order> Convert(OrderDtoList source, List<Order> destination, ResolutionContext context)
    {
        return context.Mapper.Map<List<Order>>(source.Orders);
    }
}

然后,您可以像这样创建映射:

public class MapperProfile : Profile
{
    public MapperProfile()
    {
        CreateMap<OrderDto, Order>();
        CreateMap<OrderDtoList, List<Order>>().ConvertUsing<OrderDtoListMapper>();
    }
}

希望这就是你要找的!

下面是一个通用扩展,如果你之前没有使用过扩展,请注意 GenericExtensions 类是一个静态类

public static class GenericExtensions {
   public static object Map<T>(this T source)
    {
        var fullName = source.GetType().FullName;
        var sourceType = source.GetType();


        var baseType = ObjectContext.GetObjectType(source.GetType());

        var config = new MapperConfiguration(cfg =>
            cfg.CreateMap(sourceType, baseType));




        var mapper = config.CreateMapper();

        var entity = mapper.Map(source, sourceType, baseType);

        return entity;

    }

}

public static List<T> Map<T>(this List<T> original)
{
        var config = new MapperConfiguration(cfg =>
            cfg.CreateMap(typeof(T), typeof(T)));

        var mapper = config.CreateMapper();       
        return original.Select(mapper.Map<T, T>).ToList();
}

用法:

对于单个实体:

var originalObject = new  Order();
originalObject.Id = 4; 
var clonedObject = originalObject.Map();

对于实体列表:

var objectList = db.ORDERS.ToList();
var clonedList = objectList.Map();

希望这可以帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM