#146 Les méthodes Find(id) des repository utilisent SingleOrDefault. Les méthodes find du repository sont utilisées dans les méthodes update au lieu de refaire une requête. Paginate est remplacé par Find[Model] pour correspondre au cahier des charges.

This commit is contained in:
josephine.vetu
2026-04-02 14:41:01 +02:00
parent ae80c3e14e
commit 198b716074
9 changed files with 73 additions and 65 deletions

View File

@@ -39,6 +39,6 @@ namespace Webzine.Repository.Contracts
/// récupérer les commentaires.</param> /// récupérer les commentaires.</param>
/// <param name="limit">Le nombre maximum de commentaires à récupérer.</param> /// <param name="limit">Le nombre maximum de commentaires à récupérer.</param>
/// <returns>Une collection de commentaires paginée.</returns> /// <returns>Une collection de commentaires paginée.</returns>
IEnumerable<Commentaire> Paginate(int offset, int limit); IEnumerable<Commentaire> FindCommentaires(int offset, int limit);
} }
} }

View File

@@ -78,7 +78,7 @@ namespace Webzine.Repository
{ {
Artiste artiste = this.context.Artistes Artiste artiste = this.context.Artistes
.Include(a => a.Titres) .Include(a => a.Titres)
.FirstOrDefault(a => a.IdArtiste == id); .SingleOrDefault(a => a.IdArtiste == id);
return artiste; return artiste;
} }
catch (Exception ex) catch (Exception ex)
@@ -112,11 +112,12 @@ namespace Webzine.Repository
try try
{ {
// .AsNoTracking() rend la requête beaucoup plus rapide pour de la lecture // .AsNoTracking() rend la requête beaucoup plus rapide pour de la lecture
// Pas besoin de faire un ToList() ici, car on retourne un IEnumerable<Artiste> et EF Core gère l'exécution différée de la requête.
var artistes = this.context.Artistes var artistes = this.context.Artistes
.AsNoTracking() .AsNoTracking()
.Include(t => t.Titres) .Include(t => t.Titres);
.ToList();
this.logger.LogDebug("{Count} artistes récupérés de la base.", artistes.Count); this.logger.LogDebug("La liste d'artistes a été récupérée de la base.");
return artistes; return artistes;
} }
catch (Exception ex) catch (Exception ex)
@@ -131,6 +132,13 @@ namespace Webzine.Repository
{ {
try 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.Artistes.Update(artiste);
this.context.SaveChanges(); this.context.SaveChanges();
this.logger.LogDebug("Artiste {Id} ({Nom}) mis à jour avec succès.", artiste.IdArtiste, artiste.Nom); this.logger.LogDebug("Artiste {Id} ({Nom}) mis à jour avec succès.", artiste.IdArtiste, artiste.Nom);
@@ -159,8 +167,7 @@ namespace Webzine.Repository
var artiste = this.context.Artistes var artiste = this.context.Artistes
.Where(a => a.Nom.ToLower().Contains(mot.ToLower())) .Where(a => a.Nom.ToLower().Contains(mot.ToLower()))
.Include(t => t.Titres) .Include(t => t.Titres)
.AsNoTracking() .AsNoTracking();
.ToList();
return artiste; return artiste;
} }
catch (Exception ex) catch (Exception ex)

View File

@@ -77,7 +77,7 @@ public class DbCommentaireRepository : ICommentaireRepository
// On inclut le titre car il est souvent affiché avec le commentaire // On inclut le titre car il est souvent affiché avec le commentaire
return this.context.Commentaires return this.context.Commentaires
.Include(c => c.Titre) .Include(c => c.Titre)
.FirstOrDefault(c => c.IdCommentaire == idCommentaire); .SingleOrDefault(c => c.IdCommentaire == idCommentaire);
} }
/// <inheritdoc/> /// <inheritdoc/>
@@ -86,15 +86,16 @@ public class DbCommentaireRepository : ICommentaireRepository
var commentaires = this.context.Commentaires var commentaires = this.context.Commentaires
.AsNoTracking() .AsNoTracking()
.Include(c => c.Titre) .Include(c => c.Titre)
.OrderByDescending(c => c.DateCreation) .OrderByDescending(c => c.DateCreation);
.ToList();
this.logger.LogDebug("Nombre de commentaires trouvés : {Count}", commentaires.Count); this.logger.LogDebug("La liste de commentaires a été récupérée.");
return commentaires; return commentaires;
} }
/// <inheritdoc/> /// <inheritdoc/>
public IEnumerable<Commentaire> Paginate(int offset, int limit) public IEnumerable<Commentaire> FindCommentaires(int offset, int limit)
{
try
{ {
this.logger.LogDebug("Recherche paginée des commentaires (offset : {Offset}, limit : {Limit})", offset, limit); this.logger.LogDebug("Recherche paginée des commentaires (offset : {Offset}, limit : {Limit})", offset, limit);
@@ -103,10 +104,14 @@ public class DbCommentaireRepository : ICommentaireRepository
.Include(c => c.Titre) .Include(c => c.Titre)
.OrderByDescending(c => c.DateCreation) .OrderByDescending(c => c.DateCreation)
.Skip(offset) .Skip(offset)
.Take(limit) .Take(limit);
.ToList();
this.logger.LogDebug("{Count} commentaires trouvés pour cette page", commentaires.Count);
return commentaires; return commentaires;
} }
catch (Exception ex)
{
this.logger.LogError(ex, "Erreur lors de la pagination des commentaires (offset : {Offset}, limit : {Limit})", offset, limit);
throw new Exception("Une erreur est survenue lors de la pagination des commentaires.", ex);
}
}
} }

View File

@@ -96,7 +96,7 @@ public class DbStyleRepository : IStyleRepository
var style = this.context.Styles var style = this.context.Styles
.AsNoTracking() .AsNoTracking()
.Include(s => s.Titres) .Include(s => s.Titres)
.FirstOrDefault(s => s.IdStyle == id); .SingleOrDefault(s => s.IdStyle == id);
if (style == null) if (style == null)
{ {
@@ -124,10 +124,9 @@ public class DbStyleRepository : IStyleRepository
var styles = this.context.Styles var styles = this.context.Styles
.AsNoTracking() .AsNoTracking()
.OrderBy(s => s.Libelle) .OrderBy(s => s.Libelle);
.ToList();
this.logger.LogDebug("{Count} styles récupérés", styles.Count); this.logger.LogDebug("La liste de styles a été récupérée.");
return styles; return styles;
} }
catch (Exception ex) catch (Exception ex)
@@ -143,15 +142,15 @@ public class DbStyleRepository : IStyleRepository
try try
{ {
this.logger.LogInformation("Mise à jour du style avec l'ID: {IdStyle}", style.IdStyle); this.logger.LogInformation("Mise à jour du style avec l'ID: {IdStyle}", style.IdStyle);
Style existingStyle = this.Find(style.IdStyle); // Vérifie que le style existe avant de tenter de le mettre à jour
var existingStyle = this.context.Styles.Find(style.IdStyle);
if (existingStyle == null) if (existingStyle == null)
{ {
this.logger.LogWarning("Style avec l'ID {IdStyle} non trouvé pour la mise à jour", style.IdStyle); this.logger.LogWarning("Style avec l'ID {IdStyle} non trouvé pour l'update.", style.IdStyle);
throw new InvalidOperationException($"Style avec l'ID {style.IdStyle} non trouvé."); throw new InvalidOperationException($"Style avec l'ID {style.IdStyle} non trouvé pour la mise à jour.");
} }
existingStyle.Libelle = style.Libelle; this.context.Styles.Update(style);
this.context.SaveChanges(); this.context.SaveChanges();
this.logger.LogDebug("Style mis à jour avec succès: {IdStyle}", style.IdStyle); this.logger.LogDebug("Style mis à jour avec succès: {IdStyle}", style.IdStyle);

View File

@@ -104,10 +104,9 @@ public class DbTitreRepository : ITitreRepository
.OrderBy(t => t.Libelle) .OrderBy(t => t.Libelle)
.Skip(offset) .Skip(offset)
.Take(limit) .Take(limit)
.AsNoTracking() .AsNoTracking();
.ToList();
this.logger.LogDebug("{Count} titres trouvés", titres.Count); this.logger.LogDebug("La liste de titres a été récupérée.");
return titres; return titres;
} }
catch (Exception ex) catch (Exception ex)
@@ -182,7 +181,7 @@ public class DbTitreRepository : ITitreRepository
{ {
this.logger.LogInformation("Mise à jour du titre avec l'ID: {IdTitre}", titre.IdTitre); this.logger.LogInformation("Mise à jour du titre avec l'ID: {IdTitre}", titre.IdTitre);
var existingTitre = this.context.Titres.Find(titre.IdTitre); Titre existingTitre = this.Find(titre.IdTitre);
if (existingTitre != null) if (existingTitre != null)
{ {
this.context.Entry(existingTitre).CurrentValues.SetValues(titre); this.context.Entry(existingTitre).CurrentValues.SetValues(titre);
@@ -228,10 +227,9 @@ public class DbTitreRepository : ITitreRepository
.Include(t => t.Styles) .Include(t => t.Styles)
.Where(t => t.Libelle.ToLower().Contains(mot.ToLower())) .Where(t => t.Libelle.ToLower().Contains(mot.ToLower()))
.OrderBy(t => t.Libelle) .OrderBy(t => t.Libelle)
.AsNoTracking() .AsNoTracking();
.ToList();
this.logger.LogDebug("{Count} titres trouvés correspondant à '{Mot}'", titres.Count, mot); this.logger.LogDebug("La liste de titres a été récupérée.");
return titres; return titres;
} }
catch (Exception ex) catch (Exception ex)
@@ -278,10 +276,9 @@ public class DbTitreRepository : ITitreRepository
.Include(t => t.Styles) .Include(t => t.Styles)
.Include(t => t.Commentaires) .Include(t => t.Commentaires)
.OrderBy(t => t.Libelle) .OrderBy(t => t.Libelle)
.AsNoTracking() .AsNoTracking();
.ToList();
this.logger.LogDebug("{Count} titres récupérés", titres.Count); this.logger.LogDebug("La liste de titres a été récupérée avec FindAll.");
return titres; return titres;
} }
catch (Exception ex) catch (Exception ex)
@@ -303,10 +300,9 @@ public class DbTitreRepository : ITitreRepository
.Include(t => t.Styles) .Include(t => t.Styles)
.Where(t => t.Styles.Any(s => s.Libelle.ToLower() == libelle.ToLower())) .Where(t => t.Styles.Any(s => s.Libelle.ToLower() == libelle.ToLower()))
.OrderBy(t => t.Libelle) .OrderBy(t => t.Libelle)
.AsNoTracking() .AsNoTracking();
.ToList();
this.logger.LogDebug("{Count} titres trouvés pour le style '{Libelle}'", titres.Count, libelle); this.logger.LogDebug("La liste de titres a été récupérée pour le style '{Libelle}'", libelle);
return titres; return titres;
} }
catch (Exception ex) catch (Exception ex)

View File

@@ -75,16 +75,16 @@ namespace Webzine.Repository
/// <inheritdoc/> /// <inheritdoc/>
public void Update(Artiste artiste) public void Update(Artiste artiste)
{ {
var stored = this.dataStore.Artistes.FirstOrDefault(a => a.IdArtiste == artiste.IdArtiste); Artiste existingArtiste = this.Find(artiste.IdArtiste);
if (stored == null) if (existingArtiste == null)
{ {
this.logger.LogWarning("L'artiste {Id} n'a pas été trouvé pour l'update.", artiste.IdArtiste); this.logger.LogWarning("L'artiste {Id} n'a pas été trouvé pour l'update.", artiste.IdArtiste);
return; return;
} }
stored.Nom = artiste.Nom; existingArtiste.Nom = artiste.Nom;
stored.Biographie = artiste.Biographie; existingArtiste.Biographie = artiste.Biographie;
stored.Titres = artiste.Titres; existingArtiste.Titres = artiste.Titres;
} }
/// <inheritdoc/> /// <inheritdoc/>

View File

@@ -47,7 +47,7 @@ namespace Webzine.Repository
/// <inheritdoc/> /// <inheritdoc/>
public Commentaire Find(int idCommentaire) public Commentaire Find(int idCommentaire)
{ {
return this.dataStore.Commentaires.FirstOrDefault(c => c.IdCommentaire == idCommentaire); return this.dataStore.Commentaires.SingleOrDefault(c => c.IdCommentaire == idCommentaire);
} }
/// <inheritdoc/> /// <inheritdoc/>
@@ -59,13 +59,12 @@ namespace Webzine.Repository
} }
/// <inheritdoc/> /// <inheritdoc/>
public IEnumerable<Commentaire> Paginate(int offset, int limit) public IEnumerable<Commentaire> FindCommentaires(int offset, int limit)
{ {
return this.dataStore.Commentaires return this.dataStore.Commentaires
.OrderByDescending(c => c.DateCreation) .OrderByDescending(c => c.DateCreation)
.Skip(offset) .Skip(offset)
.Take(limit) .Take(limit);
.ToList();
} }
} }
} }

View File

@@ -55,15 +55,15 @@ public class LocalStyleRepository : IStyleRepository
/// <inheritdoc/> /// <inheritdoc/>
public void Update(Style style) public void Update(Style style)
{ {
var stored = this.dataStore.Styles.FirstOrDefault(s => s.IdStyle == style.IdStyle); Style existingStyle = this.Find(style.IdStyle);
if (stored == null) if (existingStyle == null)
{ {
this.logger.LogWarning("Style with id {IdStyle} not found for update.", style.IdStyle); this.logger.LogWarning("Style with id {IdStyle} not found for update.", style.IdStyle);
return; return;
} }
stored.Libelle = style.Libelle; existingStyle.Libelle = style.Libelle;
stored.Titres = style.Titres; existingStyle.Titres = style.Titres;
} }
/// <inheritdoc/> /// <inheritdoc/>

View File

@@ -96,7 +96,7 @@ public class LocalTitreRepository : ITitreRepository
public Titre Find(int idTitre) public Titre Find(int idTitre)
{ {
return this.dataStore.Titres return this.dataStore.Titres
.FirstOrDefault(t => t.IdTitre == idTitre); .SingleOrDefault(t => t.IdTitre == idTitre);
} }
/// <inheritdoc/> /// <inheritdoc/>
@@ -115,18 +115,20 @@ public class LocalTitreRepository : ITitreRepository
/// <inheritdoc/> /// <inheritdoc/>
public void Update(Titre titre) public void Update(Titre titre)
{ {
var stored = this.dataStore.Titres.FirstOrDefault(t => t.IdTitre == titre.IdTitre); // On trouve le titre stocké pour mettre à jour ses propriétés avec la méthode Find du repository
if (stored == null) // pour éviter la duplication de code.
Titre existingTitre = this.Find(titre.IdTitre);
if (existingTitre == null)
{ {
this.logger.LogWarning("Titre avec l'ID {Id} non trouvé pour mise à jour.", titre.IdTitre); this.logger.LogWarning("Titre avec l'ID {Id} non trouvé pour mise à jour.", titre.IdTitre);
return; return;
} }
stored.Libelle = titre.Libelle; existingTitre.Libelle = titre.Libelle;
stored.DateCreation = titre.DateCreation; existingTitre.DateCreation = titre.DateCreation;
stored.NbLectures = titre.NbLectures; existingTitre.NbLectures = titre.NbLectures;
stored.NbLikes = titre.NbLikes; existingTitre.NbLikes = titre.NbLikes;
stored.IdArtiste = titre.IdArtiste; existingTitre.IdArtiste = titre.IdArtiste;
stored.Styles = titre.Styles; existingTitre.Styles = titre.Styles;
} }
} }