The following code leads to a Value cannot be null. (Parameter 'source') exception. It is caused by .ProjectTo and more specifically it is caused by DisciplineHours in DisciplineDto. It's probably hard to tell what's causing it, but how do I trace it back?
It's probably smt like .ThenInclude(discipline => discipline.DisciplineHours).
fail: AcademicSchedule.Application.Disciplines.Queries.GetDisciplinesByFlowIdQuery[0] Request: Unhandled Exception for Request GetDisciplinesByFlowIdQuery AcademicSchedule.Application.Disciplines.Queries.GetDisciplinesByFlowIdQuery System.ArgumentNullException: Value cannot be null. (Parameter 'source') at System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument) at System.Linq.Enumerable.Select[TSource,TResult](IEnumerable
1 source, Func2 selector) at lambda_method274(Closure , Discipline ) at System.Linq.Enumerable.SelectListIterator2.MoveNext() at System.Collections.Generic.List1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source)
using Response = List<DisciplineDto>;
public class GetDisciplinesByFlowIdQuery : IRequest<Response>
{
public int FlowId { get; set; }
}
public class GetDisciplinesByFlowIdQueryHandler : IRequestHandler<GetDisciplinesByFlowIdQuery, Response>
{
private readonly IApplicationDbContext _context;
private readonly IMapper _mapper;
public GetDisciplinesByFlowIdQueryHandler(IApplicationDbContext context, IMapper mapper)
{
_context = context;
_mapper = mapper;
}
public Task<Response> Handle(GetDisciplinesByFlowIdQuery request, CancellationToken cancellationToken)
{
var flow = _context.Flows
.Include(f => f.Disciplines)
.SingleOrDefault(x => x.Id == request.FlowId);
if (flow == null)
{
throw new NotFoundException(nameof(Flow), request.FlowId);
}
var result = flow.Disciplines
.AsQueryable()
.ProjectTo<DisciplineDto>(_mapper.ConfigurationProvider)
.ToList();
return Task.FromResult(result);
}
}
public class DisciplineDto : IMapFrom<Discipline>
{
public int Id { get; set; }
public string ShortName { get; set; }
public string FullName { get; set; }
public string DisciplineCode { get; set; }
public int SemesterNumber { get; set; }
public bool IsRequired { get; set; }
public string CurriculumCode { get; set; }
public int CurriculumVersion { get; set; }
public DepartmentDto Department { get; set; }
public PeriodDto Period { get; set; }
public List<DisciplineHourDto> DisciplineHours { get; set; } // Caused by this line
}
public class Discipline
{
public int Id { get; set; }
public string ShortName { get; set; }
public string FullName { get; set; }
public string DisciplineCode { get; set; }
public int SemesterNumber { get; set; }
public bool IsRequired { get; set; }
public string CurriculumCode { get; set; }
public int CurriculumVersion { get; set; }
public int DepartmentId { get; set; }
public Department Department { get; set; }
public int PeriodId { get; set; }
public Period Period { get; set; }
public List<Flow> Flows { get; set; }
public List<DisciplineHour> DisciplineHours { get; set; }
public List<ClassActivity> ClassActivities { get; set; }
}
public class Flow
{
public int Id { get; set; }
public int PeriodId { get; set; }
public Period Period { get; set; }
public List<Discipline> Disciplines { get; set; }
public List<Subgroup> Subgroups { get; set; }
public List<ClassActivity> ClassActivities { get; set; }
}
public class DisciplineHour
{
public int DisciplineId { get; set; }
public Discipline Discipline { get; set; }
public int ClassActivityTypeId { get; set; }
public ClassActivityType ClassActivityType { get; set; }
public decimal Hours { get; set; }
}
public class DisciplineHourDto : IMapFrom<DisciplineHour>
{
public int DisciplineId { get; set; }
public int ClassActivityTypeId { get; set; }
public decimal Hours { get; set; }
public string DisciplineName { get; set; }
public string ClassActivityTypeName { get; set; }
public string FullName { get; set; }
public void Mapping(Profile profile)
{
profile.CreateMap<DisciplineHour, DisciplineHourDto>()
.ForMember(dto => dto.DisciplineName, opt => opt.MapFrom(sh => sh.Discipline.FullName))
.ForMember(dto => dto.ClassActivityTypeName, opt => opt.MapFrom(sh => sh.ClassActivityType.ShortName))
.ForMember(dto => dto.FullName, opt => opt.MapFrom(sh => $"{sh.ClassActivityType.FullName} {sh.Discipline.ShortName}"));
}
}