Handler.cs 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Microsoft.EntityFrameworkCore;
  4. namespace Application.Features.Api.Crew.GetCrewList;
  5. internal sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Response>
  6. {
  7. public async Task<Response> Handle(Query request, CancellationToken ct)
  8. {
  9. var query = db.Crew.AsNoTracking().Where(c => c.ChannelID == request.ChannelID);
  10. var total = await query.CountAsync(ct);
  11. // 정렬을 Select 전 엔티티 위에서 수행 (EF Core SQL 변환 가능)
  12. var sorted = (request.SortBy, request.SortDir) switch
  13. {
  14. ("amount", "asc") => query.OrderBy(c => c.Sessions.Sum(s => s.TotalAmount)),
  15. ("amount", _) => query.OrderByDescending(c => c.Sessions.Sum(s => s.TotalAmount)),
  16. ("members", "asc") => query.OrderBy(c => c.Members.Count(m => m.IsActive)),
  17. ("members", _) => query.OrderByDescending(c => c.Members.Count(m => m.IsActive)),
  18. ("date", "asc") => query.OrderBy(c => c.CreatedAt),
  19. _ => query.OrderByDescending(c => c.CreatedAt)
  20. };
  21. var list = await sorted
  22. .Skip((request.PageNum - 1) * request.PerPage)
  23. .Take(request.PerPage)
  24. .Select(c => new CrewItem(
  25. c.ID, c.Name, c.Description, c.MinAmount, c.IsActive,
  26. c.Members.Count(m => m.IsActive),
  27. c.Sessions.Count,
  28. c.Sessions.Sum(s => s.TotalAmount),
  29. c.CreatedAt
  30. ))
  31. .ToListAsync(ct);
  32. return new Response(total, list);
  33. }
  34. }