diff --git a/Francesco.Recipes.World/Repositories/Recipe/IRecipeRepository.cs b/Francesco.Recipes.World/Repositories/Recipe/IRecipeRepository.cs index 5afb2f0..ebbc8c7 100644 --- a/Francesco.Recipes.World/Repositories/Recipe/IRecipeRepository.cs +++ b/Francesco.Recipes.World/Repositories/Recipe/IRecipeRepository.cs @@ -1,5 +1,6 @@ namespace Francesco.Recipes.World.Repositories.Recipe { + using Francesco.Recipes.World.Models; using Francesco.Recipes.World.Models.BackendModels.Category; using Francesco.Recipes.World.Models.BackendModels.Recipe; @@ -17,8 +18,7 @@ Task CreateRecipeForCategoryAsync(Category category, string name, string description, Difficulty difficulty, int servings, TimeSpan preparationTime, TimeSpan cookingTime); - Task> SearchInRecipesAndIngredients(string searchterm); - Task DeleteRecipeAsync(Guid recipeId); + Task> SearchInRecipesAndIngredients(string searchTerm); } } diff --git a/Francesco.Recipes.World/Repositories/Recipe/RecipeRepository.cs b/Francesco.Recipes.World/Repositories/Recipe/RecipeRepository.cs index 73c76a7..d097f7d 100644 --- a/Francesco.Recipes.World/Repositories/Recipe/RecipeRepository.cs +++ b/Francesco.Recipes.World/Repositories/Recipe/RecipeRepository.cs @@ -1,6 +1,7 @@ namespace Francesco.Recipes.World.Repositories.Recipe { using Francesco.Recipes.World.Data; + using Francesco.Recipes.World.Models; using Francesco.Recipes.World.Models.BackendModels.Category; using Francesco.Recipes.World.Models.BackendModels.Ingredient; using Francesco.Recipes.World.Models.BackendModels.Recipe; @@ -148,21 +149,67 @@ await _context.SaveChangesAsync(); } - public async Task> SearchInRecipesAndIngredients(string searchTerm) + public async Task> SearchInRecipesAndIngredients(string searchTerm) { - var queryable = _context.Recipes - .Include(r => r.RecipeIngredients) - .ThenInclude(ri => ri.Ingredient) - .AsQueryable(); - - if (!string.IsNullOrWhiteSpace(searchTerm)) + try { - searchTerm = searchTerm.ToLower(); - queryable = queryable.Where(r => r.Name.ToLower().Contains(searchTerm) || - r.RecipeIngredients.Any(ri => ri.Ingredient.Name.ToLower().Contains(searchTerm))); - } + if (string.IsNullOrWhiteSpace(searchTerm)) + { + return await _context.Recipes + .OrderByDescending(r => r.CreatedAt) + .Take(20) + .Select(r => new SearchViewModel + { + Id = r.Id, + Name = r.Name, + Description = r.Description, + IsFavorite = r.IsFavorite, + ImageData = r.MediaFiles + .Where(m => m.MimeType != null && m.MimeType.StartsWith("image/")) + .Select(m => m.Data) + .FirstOrDefault(), + MimeType = r.MediaFiles + .Where(m => m.MimeType != null && m.MimeType.StartsWith("image/")) + .Select(m => m.MimeType) + .FirstOrDefault(), + Ingredients = r.RecipeIngredients.Select(ri => ri.Ingredient.Name).ToList(), + TotalTime = r.PreparationTime.Add(r.CookingTime), + }) + .ToListAsync(); + } - return await queryable.ToListAsync(); + var normalizedSearchTerm = searchTerm.ToLower(); + + return await _context.Recipes + .Where(r => EF.Functions.Like(r.Name.ToLower(), $"%{normalizedSearchTerm}%") || + (r.Description != null && EF.Functions.Like(r.Description.ToLower(), $"%{normalizedSearchTerm}%")) || + r.RecipeIngredients.Any(ri => EF.Functions.Like(ri.Ingredient.Name.ToLower(), $"%{normalizedSearchTerm}%"))) + .OrderByDescending(r => r.CreatedAt) + .Take(100) + .Select(r => new SearchViewModel + { + Id = r.Id, + Name = r.Name, + Description = r.Description, + IsFavorite = r.IsFavorite, + ImageData = r.MediaFiles + .Where(m => m.MimeType != null && m.MimeType.StartsWith("image/")) + .Select(m => m.Data) + .FirstOrDefault(), + MimeType = r.MediaFiles + .Where(m => m.MimeType != null && m.MimeType.StartsWith("image/")) + .Select(m => m.MimeType) + .FirstOrDefault(), + Ingredients = r.RecipeIngredients.Select(ri => ri.Ingredient.Name).ToList(), + TotalTime = r.PreparationTime.Add(r.CookingTime), + }) + .ToListAsync(); + } + catch (Exception ex) + { + Console.WriteLine($"Error in SearchInRecipesAndIngredientsOptimized: {ex.Message}"); + return new List(); + } } public async Task> GetRecipesByDifficultyAsync(Difficulty? difficulty)