Использование string.Split() в проблеме AutoMapper

У меня есть основное приложение ASP .Net. Я просто пытаюсь настроить AutoMapper для преобразования строки, разделенной запятой, в список строк в соответствии с этой конфигурацией:

configuration.CreateMap<Job, JobDto>()
             .ForMember(dto => dto.Keywords, options => options.MapFrom(entity => entity.Keywords.Split(',').ToList()))

По какой-то причине он не компилируется и выдает следующую ошибку:

Дерево выражений не может содержать вызов или вызов, использующий необязательный аргумент.

Я не понимаю, почему я получаю эту ошибку. Я почти уверен, что делал это в других своих проектах раньше без такой ошибки.


person Mohammad Shadmehr    schedule 25.02.2019    source источник
comment
Это подходит для меня. Попробуйте обновить АМ. Реплика поможет. Создайте суть, которую мы можем выполнить и увидеть ошибку.   -  person Lucian Bargaoanu    schedule 25.02.2019


Ответы (4)


Это совершенно верно.

Ошибка возникает из-за того, что создаваемое дерево выражений должно содержать более сложную логику, такую ​​как .Split(',').ToList(), которая не является доступным свойством или методом, поддерживаются только свойства и методы отраженного объекта верхнего уровня (например, класс MemberInfo).

Цепочка свойств, глубокие вызовы (.obj1property.obj2property), методы расширения не поддерживаются деревьями выражений, как в этом вызове .ToList().

Мое решение было таким:

// Execute a custom function to the source and/or destination types after member mapping
configuration.CreateMap<Job, JobDto>()
  .AfterMap((dto,jobDto)=>jobDto.Keywords = dto.Keywords.Split(',').ToList());
person Artur Mustafin    schedule 25.02.2019
comment
вроде как для IQueryable, хотелось бы узнать как, спасибо - person Rafi Henig; 04.12.2020

Как говорит ошибка, функция Split имеет необязательный параметр. Полная подпись выглядит следующим образом (options является необязательным)

public string[] Split(string separator, StringSplitOptions options = StringSplitOptions.None)

Поскольку вы пытаетесь использовать функцию со значением по умолчанию внутри дерева выражений, это дает вам ошибку. Чтобы исправить это, просто передайте необязательные параметры самостоятельно. ( StringSplitOptions.None ) Итак, просто измените его на это:

entity.Keywords.Split(',' , StringSplitOptions.None).ToList()
person Ali Abdoli    schedule 06.09.2019

У меня такая же проблема. Я не знаю, является ли это проблемой или нет. Во всяком случае, я нашел обходной путь.

 CreateMap<Category, GetCategoryRest>()
                .ForMember(dest => dest.Words, 
                    opt => opt.MapFrom(src => ToWordsList(src.Words)));

 private static List<string> ToWordsList(string words)
 {
   return string.IsNullOrWhiteSpace(words) ? new List<string>() : words.Split(",").ToList();
 }

Гарантируется, что AutoMapper всегда имеет List. Тем не менее, я в замешательстве. В моем Startup.cs я определяю, что AutoMapper допускает нулевые значения для списка.

Mapper.Initialize(cfg => {
 cfg.AllowNullCollections = true;
}

Category.Words is a string. GetCategoryRest.Words is a List<string>

Версия AutoMapper: 8.1.1, AutoMapper.Microsoft.DependencyInjection: 6.1.1

person kuzdu    schedule 13.06.2019

Используйте .AfterMap

 CreateMap<src, dto>()
                .ForMember(src =>src.Categories,options=> options.Ignore())
                .AfterMap((src, dto) => { dto.Categories.AddRange(src.Categories.Split(",").ToList()); })
                .ReverseMap()
                .ForMember(src => src.Categories, option => option.MapFrom(dto => string.Join(",", dto.Categories)));
person Mark Macneil Bikeio    schedule 31.07.2020