Finished Project

This commit is contained in:
Francesco Lorenzo D'Amico
2026-03-02 16:35:32 +01:00
parent 247fbd6ae9
commit b546d8946e
21 changed files with 333 additions and 205 deletions
@@ -4,8 +4,10 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Francesco.Recipes.World.Data;
using Francesco.Recipes.World.Models;
using Francesco.Recipes.World.Models.BackendModels.Category;
using Francesco.Recipes.World.Models.BackendModels.Recipe;
using Francesco.Recipes.World.Views.Category;
using Microsoft.EntityFrameworkCore;
public class CategoryRepository : ICategoryRepository
@@ -44,11 +46,44 @@
public async Task<IEnumerable<Category>> GetAllCategoriesWithRecipesAsync()
{
return await _context.Categories
.Include(c => c.Recipes)
.ThenInclude(r => r.MediaFiles)
.AsSplitQuery()
var categories = await _context.Categories
.Include(c => c.Recipes.OrderByDescending(r => r.CreatedAt).Take(3))
.ThenInclude(r => r.MediaFiles.Take(2))
.AsSplitQuery()
.ToListAsync();
return categories;
}
public async Task<IEnumerable<CategoryRecipesViewModel>> GetAllCategoriesWithRecipesViewModelAsync()
{
var categories = await _context.Categories
.Select(c => new CategoryRecipesViewModel
{
Category = c,
Recipes = c.Recipes
.OrderByDescending(r => r.CreatedAt)
.Take(3)
.Select(r => new RecipeCardViewModel
{
Id = r.Id,
Name = r.Name,
CookingTime = r.CookingTime,
IsFavorite = r.IsFavorite,
ImageData = r.MediaFiles
.OrderBy(m => m.Id)
.Select(m => m.Data)
.FirstOrDefault(),
MimeType = r.MediaFiles
.OrderBy(m => m.Id)
.Select(m => m.MimeType)
.FirstOrDefault(),
}),
})
.AsSplitQuery()
.ToListAsync();
return categories;
}
}
}
@@ -5,6 +5,7 @@
using System.Threading.Tasks;
using Francesco.Recipes.World.Models.BackendModels.Category;
using Francesco.Recipes.World.Models.BackendModels.Recipe;
using Francesco.Recipes.World.Views.Category;
public interface ICategoryRepository
{
@@ -15,5 +16,7 @@
Task<IEnumerable<Recipe>> GetRecipesByCategoryAsync(Guid categoryId);
Task<IEnumerable<Category>> GetAllCategoriesWithRecipesAsync();
Task<IEnumerable<CategoryRecipesViewModel>> GetAllCategoriesWithRecipesViewModelAsync();
}
}
@@ -19,6 +19,7 @@
.Where(r => r.IsFavorite)
.Include(r => r.Favorite)
.Include(r => r.MediaFiles)
.Take(6)
.ToListAsync();
}
@@ -19,6 +19,7 @@
Task<Recipe> CreateRecipeForCategoryAsync(Category category, string name, string description, Difficulty difficulty, int servings, TimeSpan preparationTime, TimeSpan cookingTime);
Task<bool> DeleteRecipeAsync(Guid recipeId);
Task<IEnumerable<SearchViewModel>> SearchInRecipesAndIngredients(string searchTerm);
}
}
@@ -198,35 +198,6 @@
.ToListAsync();
}
private static Expression<Func<Recipe, SearchViewModel>> SearchViewModelSelector()
{
return 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(ContentType.Image))
.Select(m => m.Data)
.FirstOrDefault(),
MimeType = r.MediaFiles
.Where(m => m.MimeType != null && m.MimeType.StartsWith(ContentType.Image))
.Select(m => m.MimeType)
.FirstOrDefault(),
Ingredients = r.RecipeIngredients.Select(ri => ri.Ingredient.Name).ToList(),
TotalTime = r.PreparationTime.Add(r.CookingTime),
};
}
private static IQueryable<Recipe> ApplyRecipeSearchFilter(IQueryable<Recipe> query, string normalizedSearchTerm)
{
return query.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}%")));
}
public async Task<bool> DeleteRecipeAsync(Guid recipeId)
{
var recipe = await GetRecipeByIdAsync(recipeId);
@@ -259,9 +230,9 @@
_context.MediaFiles.RemoveRange(recipe.MediaFiles);
}
if (recipe.Favorit != null && recipe.Favorit.Id != Guid.Empty)
if (recipe.Favorite != null && recipe.Favorite.Id != Guid.Empty)
{
_context.Remove(recipe.Favorit);
_context.Remove(recipe.Favorite);
}
_context.Recipes.Remove(recipe);
@@ -269,5 +240,34 @@
await _context.SaveChangesAsync();
return true;
}
private static Expression<Func<Recipe, SearchViewModel>> SearchViewModelSelector()
{
return 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(ContentType.Image))
.Select(m => m.Data)
.FirstOrDefault(),
MimeType = r.MediaFiles
.Where(m => m.MimeType != null && m.MimeType.StartsWith(ContentType.Image))
.Select(m => m.MimeType)
.FirstOrDefault(),
Ingredients = r.RecipeIngredients.Select(ri => ri.Ingredient.Name).ToList(),
TotalTime = r.PreparationTime.Add(r.CookingTime),
};
}
private static IQueryable<Recipe> ApplyRecipeSearchFilter(IQueryable<Recipe> query, string normalizedSearchTerm)
{
return query.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}%")));
}
}
}