Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ProjectionTo return ArgumentException: Argument types do not match

I try to build, some small chat app, first of all, I tried to fetch the list of created chat rooms, but when I fetch data from DB and try to map this by the Queryable Extensions: IQueariable.ProjectionTo() I got the error with a custom field. I use PostgreSQL, Automapper, EF core.

If i first serialize this list, it's working, but it looks dirty to me: two operations instead one. for example, this works fine:

var rooms = await _context.Set<Chat>()
                .ToListAsync()
                ;
return Mapper.Map<List<ChatDto>>(rooms);

by the way, if i ignore Name props in Automapper profile, its works too! Even derived collection!

on the other hand, i thought its problem in different types of fields (i rarely use postgre), but if i change mapping, like this:

CreateMap<Chat, ChatDto>()
                .ForMember(x => x.Name, opt => opt.MapFrom(x => x.Id.ToString()));

i got the same error ArgumentException: Argument types do not match, but id map fine.

its return exception:

var test = _context.Set<Chat>()
                    .ProjectTo<ChatDto>()
                    .ToListAsync()
                ;

part of stacktrace:

System.ArgumentException: Argument types do not match
   at System.Linq.Expressions.Expression.Bind(MemberInfo member, Expression expression)
   at AutoMapper.QueryableExtensions.Impl.EnumerableExpressionBinder.BindEnumerableExpression(IConfigurationProvider configuration, PropertyMap propertyMap, ExpressionRequest request, ExpressionResolutionResult result, IDictionary`2 typePairCount, LetPropertyMaps letPropertyMaps) in C:\projects\automapper\src\AutoMapper\QueryableExtensions\Impl\EnumerableExpressionBinder.cs:line 37
   at AutoMapper.QueryableExtensions.Impl.EnumerableExpressionBinder.Build(IConfigurationProvider configuration, PropertyMap propertyMap, TypeMap propertyTypeMap, ExpressionRequest request, ExpressionResolutionResult result, IDictionary`2 typePairCount, LetPropertyMaps letPropertyMaps) in C:\projects\automapper\src\AutoMapper\QueryableExtensions\Impl\EnumerableExpressionBinder.cs:line 16
   at AutoMapper.QueryableExtensions.ExpressionBuilder.<>c__DisplayClass17_0.<CreateMemberBindings>g__CreateMemberBinding|0(PropertyMap propertyMap) in C:\projects\automapper\src\AutoMapper\QueryableExtensions\ExpressionBuilder.cs:line 290

ChatEntity:

public class Chat : HasId<Guid>
    {
        public string Name { get; set; }

        public ICollection<ChatMember> ChatMembers { get; } = new List<ChatMember>();
    }

Dto:

public class ChatDto
    {
        public Guid Id { get; set; }

        public string Name { get; set; }

        public ChatMemberDto[] ChatMembers { get; set; }
    }

Mapping:

CreateMap<Chat, ChatDto>()
                .ForMember(x => x.Name, opt => opt.MapFrom(x => x.Name));

I clearly indicated the mapping of this field, although this is not required, of course

I try to check the execution plan, like this:

var test = _context.Set<Chat>()
                .ProjectTo<ChatDto>()
                .Expression;

but still, the same result.

Thank you for your help!

like image 868
Eduard M Avatar asked Nov 16 '22 15:11

Eduard M


1 Answers

In case you didn't know, AutoMapper automatically maps arguments that have the same name automatically. What I suspect is happening here, is that ChatEntity.ChatMembers, an ICollection, is conflicting when mapping to a ChatMemberDto[] on Dto.ChatMembers.

like image 190
André Dias Avatar answered Jan 16 '23 10:01

André Dias