- Add AutoMapper profile for CfgProfile and ProfileSqlJob entity-to-DTO mappings - Consolidate GetProfileByIdQuery and GetAllActiveProfilesQuery into unified GetProfileQuery - Implement flexible filtering with nullable query options (Id, Active, TypeId, ProfileName) - Add IncludeSqlJobs option for optimized SQL job loading - Move CfgProfileDto to Common/Dtos for better architecture alignment - Add comprehensive unit tests for GetProfileQuery with multiple filter scenarios - Move ISQLExecutor interface from Domain to Application layer - Add GetByIdWithSqlJobsAsync and GetAllActiveWithSqlJobsAsync to repository
125 lines
4.6 KiB
C#
125 lines
4.6 KiB
C#
using AutoMapper;
|
|
using ECMJobRunner.Application.Common.Dtos;
|
|
using ECMJobRunner.Domain.Interfaces;
|
|
using MediatR;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace ECMJobRunner.Application.DEXJob.Queries
|
|
{
|
|
/// <summary>
|
|
/// Query to retrieve profiles with flexible filtering options
|
|
/// All query options are nullable - when no filters are specified, returns all profiles
|
|
/// </summary>
|
|
public class GetProfileQuery : IRequest<List<CfgProfileDto>>
|
|
{
|
|
/// <summary>
|
|
/// Profile ID to retrieve (optional)
|
|
/// When specified, returns only the profile with this ID
|
|
/// </summary>
|
|
public long? Id { get; set; }
|
|
|
|
/// <summary>
|
|
/// Filter by active status (optional)
|
|
/// When null, returns both active and inactive profiles
|
|
/// When true, returns only active profiles
|
|
/// When false, returns only inactive profiles
|
|
/// </summary>
|
|
public bool? Active { get; set; }
|
|
|
|
/// <summary>
|
|
/// Filter by profile type (optional)
|
|
/// When specified, returns only profiles with this type
|
|
/// Type: 0 = ADSync; 1 = GraphQL; 2 = SQL-Job; 3 = SQL and REST-Job
|
|
/// </summary>
|
|
public byte? TypeId { get; set; }
|
|
|
|
/// <summary>
|
|
/// Filter by profile name (optional)
|
|
/// When specified, returns profiles with matching name (case-insensitive contains)
|
|
/// </summary>
|
|
public string? ProfileName { get; set; }
|
|
|
|
/// <summary>
|
|
/// Include associated SQL jobs in the result (optional)
|
|
/// Default: true
|
|
/// </summary>
|
|
public bool IncludeSqlJobs { get; set; } = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handler for GetProfileQuery
|
|
/// Retrieves profiles with optional filtering and uses AutoMapper for DTO mapping
|
|
/// </summary>
|
|
public class GetProfileQueryHandler : IRequestHandler<GetProfileQuery, List<CfgProfileDto>>
|
|
{
|
|
private readonly ICfgProfileRepository _profileRepository;
|
|
private readonly IMapper _mapper;
|
|
|
|
public GetProfileQueryHandler(ICfgProfileRepository profileRepository, IMapper mapper)
|
|
{
|
|
_profileRepository = profileRepository;
|
|
_mapper = mapper;
|
|
}
|
|
|
|
public async Task<List<CfgProfileDto>> Handle(GetProfileQuery request, CancellationToken cancellationToken)
|
|
{
|
|
IEnumerable<Domain.Entities.CfgProfile> profiles;
|
|
|
|
// If ID is specified, get single profile by ID
|
|
if (request.Id.HasValue)
|
|
{
|
|
var profile = request.IncludeSqlJobs
|
|
? await _profileRepository.GetByIdWithSqlJobsAsync(request.Id.Value, cancellationToken)
|
|
: await _profileRepository.GetByIdAsync(request.Id.Value, cancellationToken);
|
|
|
|
profiles = profile != null ? new[] { profile } : [];
|
|
}
|
|
// Otherwise, get profiles with filters
|
|
else
|
|
{
|
|
// Get all profiles with SQL jobs if requested
|
|
if (request.IncludeSqlJobs)
|
|
{
|
|
// If Active filter is specified and true, use optimized method
|
|
if (request.Active.HasValue && request.Active.Value)
|
|
{
|
|
profiles = await _profileRepository.GetAllActiveWithSqlJobsAsync(cancellationToken);
|
|
}
|
|
else
|
|
{
|
|
// Generic query with filters
|
|
profiles = await _profileRepository.FindAsync(p => true, cancellationToken);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
profiles = await _profileRepository.GetAllAsync(cancellationToken);
|
|
}
|
|
|
|
// Apply filters
|
|
if (request.Active.HasValue)
|
|
{
|
|
profiles = profiles.Where(p => p.Active == request.Active.Value);
|
|
}
|
|
|
|
if (request.TypeId.HasValue)
|
|
{
|
|
profiles = profiles.Where(p => p.TypeId == request.TypeId.Value);
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(request.ProfileName))
|
|
{
|
|
var searchName = request.ProfileName.ToLowerInvariant();
|
|
profiles = profiles.Where(p => p.ProfileName.ToLowerInvariant().Contains(searchName));
|
|
}
|
|
}
|
|
|
|
// Use AutoMapper to map entities to DTOs
|
|
return _mapper.Map<List<CfgProfileDto>>(profiles.ToList());
|
|
}
|
|
}
|
|
}
|