Сопоставить свойство со списком объектов с помощью AutoMapper CreateMap - PullRequest
1 голос
/ 08 января 2020

Прежде всего, извините, мой Engli sh:)

Я использую AutoMapper для отображения между классами.

У меня есть структура классов, подобная приведенной ниже.

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

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

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

Моя проблема в том, что я хочу отобразить объект OrderDtoList в List с помощью профиля AutoMapping.

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

Но я не могу понять, как написать функцию CreateMap <> ().

Пожалуйста, помогите.

Ответы [ 3 ]

3 голосов
/ 08 января 2020

Немного сложно получить его с нуля, но это возможно. Вы должны создать 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);
    }
}

Как упоминал Люциан, существует перегрузка 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);
}
3 голосов
/ 08 января 2020

Вы можете создать класс, который реализует ITypeConverter и создать отображение, используя 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>();
    }
}

Надеюсь, это то, что вы искали!

0 голосов
/ 08 января 2020

ниже является обобщенным c расширением , если вы ранее не использовали расширение, обратите внимание, что класс GenericExtensions является классом c *

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();

Надеюсь, это поможет!

...