Handler.cs 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. using Application.Abstractions.Data;
  2. using Application.Abstractions.Messaging;
  3. using Microsoft.EntityFrameworkCore;
  4. namespace Application.Features.Api.Stocks.GetList;
  5. internal sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Response>
  6. {
  7. private const ushort MaxPerPage = 100;
  8. public async Task<Response> Handle(Query request, CancellationToken ct)
  9. {
  10. var page = request.Page < 1 ? 1 : request.Page;
  11. var perPage = request.PerPage is 0 or > MaxPerPage ? (ushort)20 : request.PerPage;
  12. var query = db.Stock.AsNoTracking().Where(c => c.IsActive);
  13. if (request.Market.HasValue)
  14. {
  15. query = query.Where(c => c.Market == request.Market.Value);
  16. }
  17. var q = request.Q?.Trim();
  18. if (!string.IsNullOrEmpty(q))
  19. {
  20. query = query.Where(c => c.Name.Contains(q) || c.Code.StartsWith(q));
  21. }
  22. var total = await query.CountAsync(ct);
  23. var list = await query
  24. .OrderBy(c => c.Name).ThenBy(c => c.Code)
  25. .Skip((page - 1) * perPage)
  26. .Take(perPage)
  27. .Select(c => new
  28. {
  29. c.Code,
  30. c.Name,
  31. c.Market,
  32. c.TradingStatus,
  33. c.LastTradingDate,
  34. c.LastClosePrice,
  35. c.LastChangeRate,
  36. c.MarketCap,
  37. // 전일 거래량 — Stock denorm 에 없어 최근 거래일(LastTradingDate)의 StockDailyPrice 를 상관 서브쿼리로 조회
  38. Volume = db.StockDailyPrice.Where(p => p.StockID == c.ID && p.TradingDate == c.LastTradingDate).Select(p => (long?)p.Volume).FirstOrDefault()
  39. })
  40. .ToListAsync(ct);
  41. return new Response
  42. {
  43. Total = total,
  44. List = [..list.Select(c => new Response.Row
  45. {
  46. Code = c.Code,
  47. Name = c.Name,
  48. Market = c.Market.ToString(),
  49. TradingStatus = c.TradingStatus.ToString(),
  50. LastTradingDate = c.LastTradingDate,
  51. ClosePrice = c.LastClosePrice,
  52. ChangeRate = c.LastChangeRate,
  53. MarketCap = c.MarketCap,
  54. Volume = c.Volume
  55. })]
  56. };
  57. }
  58. }