J'ai deux racines agrégées dans mon domaine, et donc deux dépôts. Nous les appellerons BookRepository et AuthorRepository, à titre d'exemple.EF, Référentiels et frontières agrégées croisées
Je suis en train de concevoir une application MVC, et une page doit afficher une table contenant une liste d'auteurs, chaque ligne montrant les détails personnels de l'auteur. À la fin de chaque rangée est un petit bouton qui peut être cliqué pour agrandir la rangée et montrer une table d'enfant détaillant les livres publiés par l'auteur. Lorsque la page est chargée, une partie ajax est exécutée pour extraire les détails de l'auteur d'un contrôleur API et afficher les données dans la table
Chaque propriété d'un objet Auteur est mappée presque directement à une colonne, à une exception près, et c'est là que j'ai un problème. Je veux que le bouton à la fin de chaque ligne soit désactivé, si et seulement si l'auteur n'a pas de livres publiés. Cela signifie qu'un booléen doit être retourné avec chaque enregistrement d'auteur, indiquant s'ils ont des livres publiés.
Mon dépôt de livre a quelques méthodes comme ceci:
public IEnumerable<Book> GetBooksForAuthor(int authorId);
public bool AnyBooksForAuthor(int authorId);
et ma classe de livre a une propriété appelée AuthorID, donc je peux récupérer l'auteur d'un livre en appelant
authorRepository.GetById(book.AuthorId);
Mon problème est que, afin de créer une rangée pour ma table ci-dessus, je dois le créer comme ceci:
IEnumerable<Author> authors = authorRepository.GetAll();
foreach (Author author in authors)
{
yield return new AuthorTableRow
{
Name = author.Name,
Age = author.Age,
Location = author.PlaceOfResidence.Name,
HasBooks = this.bookRepository.AnyBooksForAuthor(author.Id)
};
}
Le code ci-dessus semble correct, mais il y a une pénalité de performance assez importante en appelant this.bookRepository.AnyBooksForAuthor (author.Id) pour chaque auteur, car il effectue un appel de base de données à chaque fois.
Idéalement, je suppose que je voudrais un AuthorTableRowRepository qui pourrait exécuter quelque chose comme ce qui suit:
public IEnumerable<AuthorTableRow> GetAll()
{
return from a in this.dbContext.Authors
select new AuthorTableRow
{
Name = a.Name,
Age = a.Age,
Location a.PlaceOfResidence.Name
HasBooks = a.Books.Any()
});
}
Je hésite à mettre cela en place pour ces raisons:
- AuthorTableRowRepository est un référentiel de AuthorTableRows, mais la ligne AuthorTable n'est pas un objet de domaine, ni une racine agrégée, et ne devrait donc pas avoir son propre référentiel. Comme Auteur et Livre sont tous deux des racines agrégées, j'ai supprimé la propriété "Livres" de l'entité Auteur, parce que je voulais que la seule façon de récupérer des livres soit via le BookRepository. Cela rend HasBooks = a.Books.Any() impossible. Je ne suis pas certain si j'impose ma propre meilleure pratique erronée ici. Il semble erroné d'obtenir des livres en obtenant un auteur via le dépôt AuthorRepository, puis en passant par sa propriété Books, et inversement en obtenant un auteur via une propriété sur un objet Book. Traverser les limites des racines agrégées serait la façon dont je l'appellerais, je suppose?
Comment les gens corrigeraient-ils cela? Mes inquiétudes sont-elles infondées? Je suis surtout préoccupé par la performance (ce qui devrait être) dans la première méthode, mais je veux adhérer à la meilleure pratique avec le modèle Repository et DDD.
Pourquoi les downvotes ...? S'il vous plaît expliquer si je peux éviter des erreurs la prochaine fois? –