// // Copyright (c) PlaceholderCompany. All rights reserved. // namespace Webzine.Repository { using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Webzine.EntitiesContext; using Webzine.Entity; using Webzine.Repository.Contracts; /// /// Initialise une classe qui implémente l'interface pour gérer les opérations de base de données liées aux artistes. /// public class DbArtisteRepository : IArtisteRepository { private readonly WebzineDbContext context; private readonly ILogger logger; /// /// Initializes a new instance of the class. /// /// Le contexte de base de données à utiliser pour accéder aux entités et effectuer des opérations de persistance. /// Le service de journalisation. public DbArtisteRepository(WebzineDbContext context, ILogger logger) { this.logger = logger; this.context = context; } /// public void Add(Artiste artiste) { try { this.context.Artistes.Add(artiste); this.context.SaveChanges(); } catch (DbUpdateException dbex) { this.logger.LogError(dbex, "Erreur de base de données lors de l'ajout de l'artiste: {id}", artiste.IdArtiste); throw; } catch (Exception ex) { this.logger.LogError(ex, "Une erreur est survenue lors de l'ajout de l'artiste {Nom}.", artiste?.Nom); throw new Exception("Une erreur est survenue lors de l'ajout de l'artiste.", ex); } } /// public void Delete(Artiste artiste) { try { this.context.Artistes.Remove(artiste); this.context.SaveChanges(); this.logger.LogDebug("L'artiste {IdArtiste} a bien été supprimé", artiste.IdArtiste); } catch (DbUpdateException dbex) { this.logger.LogError(dbex, "Erreur de base de données lors de la suppression de l'artiste: {Id}", artiste.IdArtiste); throw; } catch (Exception ex) { this.logger.LogError(ex, "Une erreur est survenue lors de la suppression de l'artiste {Nom}.", artiste?.Nom); throw new Exception("Une erreur est survenue lors de la suppression de l'artiste.", ex); } } /// public Artiste Find(int id) { try { Artiste artiste = this.context.Artistes .Include(a => a.Titres) .SingleOrDefault(a => a.IdArtiste == id); return artiste; } catch (Exception ex) { this.logger.LogError(ex, "Erreur lors de la recherche de l'artiste: {Id}", id); throw; } } /// public Artiste FindByName(string nom) { try { var artiste = this.context.Artistes .Include(a => a.Titres) .FirstOrDefault(a => a.Nom == nom); return artiste; } catch (Exception ex) { this.logger.LogError(ex, "Erreur lors de la recherche de l'artiste avec le nom: {Nom}", nom); throw; } } /// public IEnumerable FindAll() { try { // .AsNoTracking() rend la requête beaucoup plus rapide pour de la lecture // Pas besoin de faire un ToList() ici, car on retourne un IEnumerable et EF Core gère l'exécution différée de la requête. var artistes = this.context.Artistes .AsNoTracking() .Include(t => t.Titres); this.logger.LogDebug("La liste d'artistes a été récupérée de la base."); return artistes; } catch (Exception ex) { this.logger.LogError(ex, "Erreur lors de la récupération de tous les artistes."); throw; } } /// public void Update(Artiste artiste) { try { Artiste existingArtiste = this.Find(artiste.IdArtiste); // Vérifie que l'artiste existe avant de tenter de le mettre à jour if (existingArtiste == null) { this.logger.LogWarning("L'artiste {Id} n'a pas été trouvé pour l'update.", artiste.IdArtiste); throw new InvalidOperationException($"L'artiste avec l'ID {artiste.IdArtiste} n'a pas été trouvé pour la mise à jour."); } this.context.Artistes.Update(artiste); this.context.SaveChanges(); this.logger.LogDebug("Artiste {Id} ({Nom}) mis à jour avec succès.", artiste.IdArtiste, artiste.Nom); } catch (DbUpdateException ex) { this.logger.LogError(ex, "Erreur de base de données lors de la mise à jour de l'artiste ID: {IdArtiste}", artiste.IdArtiste); throw; } catch (Exception ex) { this.logger.LogError(ex, "Erreur lors de la mise à jour de l'artiste {Id}.", artiste.IdArtiste); throw; } } /// public IEnumerable Search(string mot) { try { // Récupération des artistes et des titres // qui leurs sont associés. // ajout de 'ToLower' pour ne pas être sensible à la casse. // NoTracking car action de lecture seulement. var artiste = this.context.Artistes .Where(a => a.Nom.ToLower().Contains(mot.ToLower())) .Include(t => t.Titres) .AsNoTracking(); return artiste; } catch (Exception ex) { throw new Exception("Erreur lors de la recherche d'artiste {error}", ex); } } /// public int Count() { try { int count = Enumerable.Count(this.context.Artistes); this.logger.LogDebug("Nombre total d'artistes dans la base: {Count}", count); return count; } catch (Exception ex) { this.logger.LogError(ex, "Erreur lors du comptage des artistes."); throw; } } /// public int Count(Func predicate) { try { int count = this.context.Artistes.Count(predicate); this.logger.LogDebug("Nombre d'artistes (avec prédicat): {Count}", count); return count; } catch (Exception ex) { this.logger.LogError(ex, "Erreur lors du comptage des artistes avec prédicat."); throw; } } /// public int CountWithBiography() { try { int count = this.context.Artistes.Count(a => !string.IsNullOrEmpty(a.Biographie)); this.logger.LogDebug("Nombre d'artistes avec biographie: {Count}", count); return count; } catch (Exception ex) { this.logger.LogError(ex, "Erreur lors du comptage des artistes avec biographie."); throw; } } /// public IEnumerable FindArtistes(int offset, int limit) { try { var artistes = this.context.Artistes .AsNoTracking() .OrderBy(a => a.Nom) .Include(t => t.Titres) .Paginate(offset, limit); this.logger.LogDebug("Page {PageNumber} d'artistes récupérée avec {PageSize} artistes par page.", offset, limit); return artistes; } catch (Exception ex) { this.logger.LogError(ex, "Erreur lors de la pagination des artistes. Page: {PageNumber}, Taille: {PageSize}", offset, limit); throw; } } } }