using Application.Abstractions.Messaging; using Application.Abstractions.Data; using Microsoft.EntityFrameworkCore; namespace Application.Features.Admin.Forum.Board.Search; public sealed class Handler(IAppDbContext db) : IQueryHandler { public async Task Handle(Query request, CancellationToken ct) { var query = db.Board.AsNoTracking().Include(c => c.BoardGroup).AsQueryable(); if (request.BoardGroupID.HasValue) { query = query.Where(c => c.BoardGroupID == request.BoardGroupID.Value); } if (!string.IsNullOrWhiteSpace(request.Keyword)) { var kw = request.Keyword.Trim(); query = query.Where(c => c.Name.Contains(kw) || c.Code.Contains(kw)); } var total = await query.CountAsync(ct); var list = await query .OrderBy(c => c.Order) .ThenByDescending(c => c.ID) .Skip((request.PageNum - 1) * request.PerPage) .Take(request.PerPage) .Select(c => new { c.ID, c.BoardGroupID, BoardGroupName = c.BoardGroup.Name, c.Code, c.Name, c.Order, c.IsSearch, c.IsActive, c.Posts, c.Comments, c.UpdatedAt, c.CreatedAt }) .ToListAsync(ct); var startNum = total - ((request.PageNum - 1) * request.PerPage); return new Response( total, [..list.Select((c, i) => new Response.Row( Num: startNum - i, c.ID, c.BoardGroupID, c.BoardGroupName, c.Code, c.Name, c.Order, c.IsSearch, c.IsActive, c.Posts, c.Comments, c.UpdatedAt, c.CreatedAt ))] ); } }