Handler.cs 1.3 KB

123456789101112131415161718192021222324252627282930313233
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Microsoft.EntityFrameworkCore;
  4. namespace Application.Features.Api.Stocks.Watch.IsWatching;
  5. /// <summary>회원이 관심 등록한 코드 집합을 조회해 요청 코드별 true/false 맵을 반환 (IsFollowing 패턴).</summary>
  6. internal sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Response>
  7. {
  8. // 방어적 상한 — 엔드포인트에서도 Take(100) 하지만 Handler 계층 자체도 무방비가 되지 않도록 (GetQuotes 패턴)
  9. public const int MaxCodes = 100;
  10. public async Task<Response> Handle(Query request, CancellationToken ct)
  11. {
  12. var codes = request.Codes.Select(c => c.Trim()).Where(c => c.Length > 0).Distinct().Take(MaxCodes).ToArray();
  13. if (codes.Length == 0)
  14. {
  15. return new Response { Map = new Dictionary<string, bool>() };
  16. }
  17. var watched = await db.StockWatch.AsNoTracking()
  18. .Where(w => w.MemberID == request.MemberID && codes.Contains(w.StockCode))
  19. .Select(w => w.StockCode)
  20. .ToListAsync(ct);
  21. var watchedSet = watched.ToHashSet();
  22. var map = codes.ToDictionary(c => c, c => watchedSet.Contains(c));
  23. return new Response { Map = map };
  24. }
  25. }