Использование 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)));