using Projects.APP.Domain;
using CORE.APP.Features;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace Projects.APP.Features.Projects
{
/// <summary>
/// Represents a request to query projects.
/// Implements IRequest to support MediatR pattern.
/// </summary>
public class ProjectQueryRequest : Request, IRequest<IQueryable<ProjectQueryResponse>>
{
}
/// <summary>
/// Represents the response for a project query.
/// </summary>
public class ProjectQueryResponse : QueryResponse
{
/// <summary>
/// Gets or sets the name of the project.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Gets or sets the description of the project.
/// </summary>
public string Description { get; set; }
/// <summary>
/// Gets or sets the URL of the project.
/// </summary>
public string Url { get; set; }
/// <summary>
/// Gets or sets the version of the project as a nullable double.
/// </summary>
public double? Version { get; set; }
/// <summary>
/// Gets or sets the formatted version of the project as a string.
/// </summary>
public string VersionF { get; set; }
public List<int> TagIds { get; set; }
}
/// <summary>
/// Handles queries related to projects by fetching data from the database.
/// Implements IRequestHandler to process ProjectQueryRequest and return a list of ProjectQueryResponse.
/// </summary>
public class ProjectQueryHandler : ProjectsDbHandler, IRequestHandler<ProjectQueryRequest, IQueryable<ProjectQueryResponse>>
{
/// <summary>
/// Initializes a new instance of the <see cref="ProjectQueryHandler"/> class.
/// </summary>
/// <param name="projectsDb">The projects database instance.</param>
public ProjectQueryHandler(ProjectsDb projectsDb) : base(projectsDb)
{
}
/// <summary>
/// Handles the request to query projects.
/// </summary>
/// <param name="request">The project query request.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>An <see cref="IQueryable{T}"/> of <see cref="ProjectQueryResponse"/>.</returns>
public Task<IQueryable<ProjectQueryResponse>> Handle(ProjectQueryRequest request, CancellationToken cancellationToken)
{
return Task.FromResult(_projectsDb.Projects
.Include(p => p.ProjectTags).ThenInclude(pt => pt.Tag)
.OrderBy(p => p.Name)
.ThenByDescending(p => p.Version)
.Select(p => new ProjectQueryResponse()
{
// Map properties from the Project entity to the response DTO.
// Optionally AutoMapper third party library (https://automapper.org/) can be used for mapping operations.
Id = p.Id,
Name = p.Name,
Description = p.Description,
Url = p.Url,
Version = p.Version,
VersionF = p.Version.HasValue ? p.Version.Value.ToString("N1") : string.Empty,
TagIds = p.TagIds
}));
}
}
}