Использование string.Split() в выпуске AutoMapper

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

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

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

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

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

1 ответ

Решение

Это полностью верно.

Ошибка возникает потому, что создаваемое дерево выражений собирается содержать более сложную логику, например .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());

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

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

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

entity.Keywords.Split(',' , StringSplitOptions.None).ToList()

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

 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 это string,GetCategoryRest.Words это List<string>

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

Используйте .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)));
Другие вопросы по тегам