using Microsoft.EntityFrameworkCore; namespace HyperBooru.Services; public interface ISearchService { public Media[] Search(string query); } public class SearchService : ISearchService { private IDbContextFactory dbFactory; public SearchService(IDbContextFactory dbFactory) => this.dbFactory = dbFactory; public Media[] Search(string query) { var db = dbFactory.CreateDbContext(); query = query.ToLower(); var matchedTag = db.TagDefinitions .FirstOrDefault(td => td.Name.ToLower() == query)?.Guid; Guid[] guids; if(matchedTag is not null) { guids = new[] { (Guid) matchedTag }; } else { guids = db.TagDefinitions .Where(td => td.Name.ToLower().Contains(query)) .Select(td => td.Guid) .ToArray(); } return db.Media .Include(m => m.Tags) .ThenInclude(m => m.TagDefinition) .AsEnumerable() .Where(m => m.Tags.IntersectBy(guids, t => t.TagDefinition.Guid).Any()) .Concat(db.Media .Where(m => (m.ShortDescription != null && m.ShortDescription.ToLower().Contains(query)) || (m.LongDescription != null && m.LongDescription.ToLower().Contains(query)))) .DistinctBy(m => m.Guid) .ToArray(); } }