4
votes

Utilisation de string.Split () dans le problème d'AutoMapper

J'ai une application principale ASP .Net. J'essaie simplement de configurer mon AutoMapper pour convertir une chaîne délimitée par une virgule en une liste de chaînes selon cette configuration:

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

Pour une raison quelconque, il n'est pas compilé et me donne l'erreur suivante :

Une arborescence d'expression ne peut pas contenir un appel ou une invocation qui utilise argument optionnel

Je ne vois pas pourquoi j'obtiens cette erreur. Je suis presque sûr que j'ai déjà fait cela dans mes autres projets sans aucune erreur de ce genre.


1 commentaires

Ça marche pour moi. Essayez de mettre à jour AM. Un repro aiderait. Créez un gist que nous pouvons exécuter et voir échouer.


4 Réponses :


3
votes

C'est tout à fait vrai.

Une erreur est générée car l'arborescence d'expression en cours de création est sur le point de contenir une logique plus complexe, comme .Split (','). ToList () , qui n'est pas une propriété ou une méthode accessible , seules les propriétés et méthodes des objets reflétés de niveau supérieur sont prises en charge (comme dans la classe MemberInfo ).

Le chaînage de propriétés, les appels profonds (.obj1property.obj2property), les méthodes d'extension ne sont pas prises en charge par les arborescences d'expression, comme dans cet appel .ToList () .

Ma solution était la suivante:

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


1 commentaires

il semble que pour IQueryable , je voudrais savoir comment, merci



2
votes

J'ai eu le même problème. Je ne sais pas si c'est un problème ou non. Quoi qu'il en soit, j'ai trouvé une solution de contournement.

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

Il est garanti que AutoMapper a toujours une Liste . Pourtant, je suis confus. Dans mon Startup.cs , je définis que AutoMapper autorise les valeurs nulles pour la liste.

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

Category.Words est une chaîne . GetCategoryRest.Words est une List

Version d'AutoMapper: 8.1.1, AutoMapper.Microsoft.DependencyInjection: 6.1.1


0 commentaires

8
votes

Comme le dit l'erreur, la fonction Split a un paramètre facultatif. La signature complète de celui-ci est la suivante ( options est facultative)

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

Lorsque vous essayez d'utiliser une fonction avec une valeur par défaut dans un arbre d'expression, cela vous donne l'erreur. Pour y remédier, rien de plus simple, transmettez vous-même les paramètres facultatifs. ( StringSplitOptions.None ) Alors, changez-le simplement en ceci:

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


0 commentaires

-1
votes

Utilisez .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)));


0 commentaires