c # - перечислить описание в строку с AutoMapper - PullRequest
0 голосов
/ 05 июня 2018

Я пытаюсь проецироваться из моей Order модели в мою OrderDTO модель.Order имеет перечисление.Проблема в том, что проекция не работает, если я пытаюсь получить атрибут Description из Enum.Вот мой код:

  • OrderStatus.cs :

    public enum OrderStatus {
        [Description("Paid")]
        Paid,
    
        [Description("Processing")]
        InProcess,
    
        [Description("Delivered")]
        Sent
    }
    
  • Order.cs :

    public class Order {
        public int Id { get; set; }
        public List<OrderLine> OrderLines { get; set; }
        public OrderStatus Status { get; set; }
    }
    
  • OrderDTO.cs :

    public class OrderDTO {
        public int Id { get; set; }
        public List<OrderLineDTO> OrderLines { get; set; }
        public string Status { get; set; }  
    }
    

При следующей конфигурации в моем AutoMapper.cs :

cfg.CreateMap<Order, OrderDTO>().ForMember(
    dest => dest.Status,
    opt => opt.MapFrom(src => src.Status.ToString())
);

Проекция работает, но я получаю OrderDTO объект, подобный этому:

 - Id: 1
 - OrderLines: List<OrderLines>
 - Sent //I want "Delivered"!

Я не хочу Status свойство «Отправлено», я хочу, чтобы оно было как связанный с ним атрибут Описание , в данном случае «Доставлено».

Я пробовал два решения, и ни одно из них не имелоработал:

  1. Использование ResolveUsing Функция AutoMapper как объяснено здесь , но, как указано здесь :

ResolveUsing не поддерживается для проекций, см. Вики на прогнозах LINQ для поддерживаемых операций.

Использование статического метода для возврата атрибута Description в String by Reflection.

cfg.CreateMap<Order, OrderDTO>().ForMember(
    dest => dest.Status,
    opt => opt.MapFrom(src => EnumHelper<OrderStatus>.GetEnumDescription(src.Status.ToString()))
);

Но при этом возникает следующая ошибка:

LINQ to Entities не распознает метод метода System.String GetEnumDescription (System.String), и этот метод нельзя преобразовать в выражение хранилища.

Тогдакак мне этого добиться?

1 Ответ

0 голосов
/ 05 июня 2018

Вы можете добавить такой метод расширения (заимствовал логику из этого поста ):

public static class ExtensionMethods
{
    static public string GetDescription(this OrderStatus This)
    {
        var type = typeof(OrderStatus);
        var memInfo = type.GetMember(This.ToString());
        var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
        return ((DescriptionAttribute)attributes[0]).Description;
    }
}

Затем получите доступ к нему на своей карте:

cfg => 
{
    cfg.CreateMap<Order, OrderDTO>()
    .ForMember
    (
        dest => dest.Status,
        opt => opt.MapFrom
        (
            src => src.Status.GetDescription()
        )
    );
}

Это приводит к тому, что вы просите:

Console.WriteLine(dto.Status);  //"Delivered", not "sent"

См. Рабочий пример по DotNetFiddle

Edit1 : не думайтеВы можете добавить локальную функцию поиска, подобную этой, к LINQ для сущностей.Это будет работать только в LINQ для объектов.Решение, которое вам следует использовать, возможно, - это таблица доменов в базе данных, которая позволяет вам присоединиться к ней и вернуть нужный столбец, чтобы вам ничего не нужно было делать с AutoMapper.

...