Search code examples
c#.net-coreautomapperdto

How to automap with a specific condition in C# .NET CORE?


I want to automap a fill workerCategory key in my specific DTO but I don't know how to do. I got no errors when I build the solution but when I make API calls it trigger an error.

Could you help me?

public class WorkerRD
    {
        public int Id { get; set; }
        public string Login { get; set; }
        public string Role { get; set; }
        public string Firstname { get; set; }
        public string Lastname { get; set; }
        public string AvatarUrl { get; set; }
        public string Iso { get; set; }
        public string Sexe { get; set; }
        public string Email { get; set; }
        public string Phone { get; set; }
        public int WorkerCategoryKey { get; set; }
        public string Address { get; set; }
        public string Postcode { get; set; }
        public string Locality { get; set; }

        public IEnumerable<TrWorkerToWorkerCategory> trWorkerToWorkerCategory { get; set; }
    }

CreateMap<TUser, WorkerRD>()
                .ForMember(
                    dest => dest.Firstname,
                    opt => opt.MapFrom(src => src.TWorker.Firstname)
                ).ForMember(
                    dest => dest.Lastname,
                    opt => opt.MapFrom(src => src.TWorker.Lastname)
                ).ForMember(
                    dest => dest.Email,
                    opt => opt.MapFrom(src => src.TWorker.Email)
                ).ForMember(
                    dest => dest.Phone,
                    opt => opt.MapFrom(src => src.TWorker.Phone)
                ).ForMember(
                    dest => dest.Sexe,
                    opt => opt.MapFrom(src => src.TWorker.Sexe)
                ).ForMember(
                    dest => dest.Address,
                    opt => opt.MapFrom(src => src.TWorker.Address)
                ).ForMember(
                    dest => dest.Postcode,
                    opt => opt.MapFrom(src => src.TWorker.Postcode)
                ).ForMember(
                    dest => dest.Locality,
                    opt => opt.MapFrom(src => src.TWorker.Locality)
                ).ForMember(
                    dest => dest.WorkerCategoryKey,
                    opt => opt.MapFrom(src => src.TWorker.TrWorkerToWorkerCategory.Where(tr => tr.IsDefault == true).Select(cat => cat.WorkerCategoryKey))
                ).ForMember(
                    dest => dest.trWorkerToWorkerCategory,
                    opt => opt.MapFrom(src => src.TWorker.TrWorkerToWorkerCategory.Where(tr => tr.IsDefault == true))
                );

My porblem is here. I want to select workerCategoryKey (integer) and map it in WorkerCategoryKey. But it doesn't work.

.ForMember(
                    dest => dest.WorkerCategoryKey,
                    opt => opt.MapFrom(src => src.TWorker.TrWorkerToWorkerCategory.Where(tr => tr.IsDefault == true).Select(cat => cat.WorkerCategoryKey))

Solution

  • The mapping you have doesn't work because you can't simply map a collection (.Select(cat => cat.WorkerCategoryKey)) to a single value (dest.trWorkerToWorkerCategory). An easy way to understand this is by doing a similar mapping manually:

    List<int> source = new List<int> { 1, 2, 3 };
    int destination = source;
    

    That doesn't make any sense, but that's essentially what you're telling AutoMapper to do with your current mapping for WorkerCategoryKey.

    With that said, it's not easy to say exactly what you need to do, because it depends on the data. But whatever it is, you need the source to be a single int. For example, if the source is always going to be a collection of the same WorkerCategoryKey, then you could just get the first item from .Select(cat => cat.WorkerCategoryKey):

    .ForMember(
        dest => dest.WorkerCategoryKey,
        opt => opt.MapFrom(src => src.TWorker.TrWorkerToWorkerCategory.Where(tr => tr.IsDefault == true).Select(cat => cat.WorkerCategoryKey).First())