I'd like to get list of tasks grouped by TaskHead with list of tasks inside.
TaskItemToReturnHeadDTO.TaskHead == TaskItemToReturnDTO.ItemStage
Entity
public class TaskItem
{
[Key]
public int TaskItemId { get; set; }
public string Name { get; set; }
public string ItemStage { get; set; }
}
DTOs
public class TaskItemToReturnHeadDTO
{
public string TaskHead { get; set; }
public ICollection<TaskItemToReturnDTO> Tasks { get; set; }
}
public class TaskItemToReturnDTO
{
public int TaskItemId { get; set; }
public string Name { get; set; }
public string ItemStage { get; set; }
}
Controller
[HttpGet("all")]
public async Task<ActionResult<ICollection<TaskItem>>> GetTasks()
{
var tasks = await _context.TaskItems.ToListAsync();
var mappedTasks = _mapper.Map<IEnumerable<TaskItemToReturnHeadDTO>>(tasks);
return Ok(mappedTasks);
}
AutoMapper Profile
CreateMap<TaskItem, TaskItemToReturnDTO>().ReverseMap();
CreateMap<TaskItemToReturnHeadDTO, TaskItem>().ReverseMap()
.ForMember(dto => dto.TaskHead, c => c.MapFrom(c => c.ItemStage))
.ForMember(dto => dto.Tasks, c => c.MapFrom(c => new List<TaskItemToReturnDTO> { new TaskItemToReturnDTO
{
TaskItemId = c.TaskItemId,
Name = c.Name,
ItemStage = c.ItemStage
}}));
This is my current result, but the tasks are not grouped.
[
{
"taskHead": "Design done",
"tasks": [
{
"taskItemId": 1,
"name": "Issuing",
"itemStage": "Design done"
}
]
},
{
"taskHead": "Design done",
"tasks": [
{
"taskItemId": 2,
"name": "Issuing",
"itemStage": "Design done"
}
]
},
{
"taskHead": "Design being checked",
"tasks": [
{
"taskItemId": 4,
"name": "SF Joists",
"itemStage": "Design being checked"
}
]
},
{
"taskHead": "Design being checked",
"tasks": [
{
"taskItemId": 5,
"name": "FF Joists",
"itemStage": "Design being checked"
}
]
},
{
"taskHead": "Being issued",
"tasks": [
{
"taskItemId": 6,
"name": "Roof",
"itemStage": "Being issued"
}
]
}
]
Below I have shown how it should look like. This is my goal.
[
{
"taskHead": "Design done",
"tasks": [
{
"taskItemId": 1,
"name": "Issuing",
"itemStage": "Design done"
},
{
"taskItemId": 2,
"name": "Issuing",
"itemStage": "Design done"
}
]
},
{
"taskHead": "Design being checked",
"tasks": [
{
"taskItemId": 4,
"name": "SF Joists",
"itemStage": "Design being checked"
},
{
"taskItemId": 5,
"name": "FF Joists",
"itemStage": "Design being checked"
}
]
},
{
"taskHead": "Being issued",
"tasks": [
{
"taskItemId": 6,
"name": "Roof",
"itemStage": "Being issued"
}
]
}
]
I think I should use GroupBy function somewhere but I cant figure out where and how. Maybe I have wrong mapping?
CodePudding user response:
Automapper works fine for TaskItemToReturnDTO
, but you don't need to crate a mapper for TaskItemToReturnHeadDTO
. Instead, use linq for grouping after mapping as follows:
var mappedTasks = _mapper.Map<IEnumerable<TaskItemToReturnDTO>>(tasks);
var groupedTasks = mappedTasks
.GroupBy(task => task.ItemStage)
.Select(group => new TaskItemToReturnHeadDTO { TaskHead = group.Key, Tasks = group.ToList() });
CodePudding user response:
@Oignon_Rouge Thank you, already figured out with pretty similar code... can you check if my version is okay? Works fine for me :)
[HttpGet("all")]
public async Task<ActionResult<ICollection<TaskItem>>> GetTasks()
{
var tasks = await _context.TaskItems.ToListAsync();
var mappedTasks = _mapper.Map<IEnumerable<TaskItemToReturnHeadDTO>>(tasks);
var groupedTasks = mappedTasks.GroupBy(z => z.TaskHead).Select(v => new TaskItemToReturnHeadDTO
{
TaskHead = v.Key,
Tasks = _mapper.Map<ICollection<TaskItemToReturnDTO>>(tasks).Where(x => x.ItemStage == v.Key).ToList()
});
return Ok(groupedTasks);
}