Как использовать Automapper ProjectTo с ConstructUsing, чтобы отобразить многие на многие, что-то вроде ConstructProjectUsing? - PullRequest
1 голос
/ 16 мая 2019

Код:

            var project = await _dbContext.TripProjects
                .Include(m => m.EmployeeTripProjects)
                .ThenInclude(m => m.Employee)
                .Where(m => m.Id == id && m.CompanyId == currentCompany.Id)
                .ProjectTo<ProjectViewDto>(Mapper.ConfigurationProvider)
                .SingleOrDefaultAsync();

Модель:

    public class TripProject
    {
        public long Id { get; set; }

        public virtual IList<EmployeeTripProject> EmployeeTripProjects { get; set; }
    }
    public class EmployeeTripProject
    {
        public long EmployeeId { get; set; }

        public virtual Employee Employee { get; set; }

        public long TripProjectId { get; set; }

        public virtual TripProject TripProject { get; set; }
    }
    public class Employee
    {
         public long Id { get; set; }

         public string LastName { get; set; }
    }

DTOS:

    public class ProjectViewDto
    {
        public long ProjectId { get; set; }

        public string Name { get; set; }

        public bool IsDeleted { get; set; }

        public IList<EmployeeViewDto> ProjectManagers { get; set; }
    }
    public class EmployeeViewDto
    {
        public long EmployeeId { get; set; }

        public string LastName { get; set; }
    }

Mappers:

            CreateMap<Employee, EmployeeViewDto>()
                .ForMember(dto => dto.EmployeeId, opt => opt.MapFrom(model => model.Id));

            CreateMap<EmployeeTripProject, EmployeeViewDto>()
                .ConstructUsing((model, ctx) => ctx.Mapper.Map<EmployeeViewDto>(model.Employee))
                .ForAllOtherMembers(opt => opt.Ignore());

            CreateMap<TripProject, ProjectViewDto>()
                .ForMember(dto => dto.ProjectId, opt => opt.MapFrom(model => model.Id))

Все работает с простой картой (без ProjectTo), но с проекцией мой sql выглядит так (не объединяется с таблицей employees) из-за параметра Func, а не Expression в ConstructUsing ( У меня 2 сотрудника с полями, которые можно обнулять):

SELECT t1.id, "t.EmployeeTripProjects".trip_project_id
FROM trips.employee_trip_project AS "t.EmployeeTripProjects"
INNER JOIN (
    SELECT t0.id
    FROM trips.trip_projects AS t0
    WHERE (t0.is_deleted = FALSE) AND ((t0.id = 1) AND (t0.company_id = 1))
    ORDER BY t0.id
    LIMIT 1
) AS t1 ON "t.EmployeeTripProjects".trip_project_id = t1.id
ORDER BY t1.id

Поэтому вопрос о том, как написать сопоставление для получения ожидаемого результата (dto с свойством mapper Employees - ProjectManagers)

...