using ErsatzTV.Application.MediaItems; using ErsatzTV.Core.Domain; using ErsatzTV.Infrastructure.Data; using Microsoft.EntityFrameworkCore; namespace ErsatzTV.Application.Search; public class SearchArtistsHandler : IRequestHandler> { private readonly IDbContextFactory _dbContextFactory; public SearchArtistsHandler(IDbContextFactory dbContextFactory) => _dbContextFactory = dbContextFactory; public async Task> Handle(SearchArtists request, CancellationToken cancellationToken) { await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken); return await dbContext.ArtistMetadata .AsNoTracking() .Where( a => EF.Functions.Like( EF.Functions.Collate(a.Title, TvContext.CaseInsensitiveCollation), $"%{request.Query}%")) .OrderBy(a => EF.Functions.Collate(a.Title, TvContext.CaseInsensitiveCollation)) .Take(10) .ToListAsync(cancellationToken) .Map(list => list.Bind(a => ToNamedMediaItem(a)).ToList()); } private static Option ToNamedMediaItem(ArtistMetadata artist) { if (string.IsNullOrWhiteSpace(artist.Title)) { return Option.None; } return new NamedMediaItemViewModel(artist.ArtistId, artist.Title); } }