Handler.cs 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Microsoft.EntityFrameworkCore;
  4. namespace Application.Features.Api.Crew.SearchMember;
  5. internal sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Response>
  6. {
  7. public async Task<Response> Handle(Query request, CancellationToken ct)
  8. {
  9. if (string.IsNullOrWhiteSpace(request.Keyword) || request.Keyword.Trim().Length < 2)
  10. {
  11. return new Response([]);
  12. }
  13. var kw = request.Keyword.Trim();
  14. // 이미 등록된 크루원의 MemberID 목록
  15. var existingMemberIDs = await db.CrewMember.AsNoTracking()
  16. .Where(m => m.CrewID == request.CrewID)
  17. .Select(m => m.MemberID)
  18. .ToListAsync(ct);
  19. var list = await db.Member.AsNoTracking()
  20. .Where(m => !m.IsWithdraw && !m.IsDenied)
  21. .Where(m => !existingMemberIDs.Contains(m.ID))
  22. .Where(m => (m.Name != null && m.Name.Contains(kw)) || m.Email.Contains(kw))
  23. .Take(20)
  24. .Select(m => new SearchResultItem(
  25. m.ID,
  26. m.Name,
  27. m.Email,
  28. m.Thumb,
  29. db.Channel.AsNoTracking()
  30. .Where(c => c.MemberID == m.ID)
  31. .Select(c => c.Name)
  32. .FirstOrDefault()
  33. ))
  34. .ToListAsync(ct);
  35. return new Response(list);
  36. }
  37. }