Comment dois-je implémenter le modèle de référentiel pour les modèles d'objets complexes?


21

Notre modèle de données comprend près de 200 classes qui peuvent être réparties en une douzaine de domaines fonctionnels. Cela aurait été bien d'utiliser des domaines, mais la séparation n'est pas aussi nette et nous ne pouvons pas la changer.

Nous repensons notre DAL pour utiliser Entity Framework et la plupart des recommandations que j'ai vues suggèrent d'utiliser un modèle de référentiel. Cependant, aucun des échantillons ne traite vraiment de modèles d'objets complexes. Certaines implémentations que j'ai trouvées suggèrent l'utilisation d'un référentiel par entité. Cela semble ridicule et irréalisable pour les grands modèles complexes.

Est-il vraiment nécessaire de créer un UnitOfWork pour chaque opération et un référentiel pour chaque entité? Je pourrais finir avec des milliers de cours. Je sais que cela est déraisonnable, mais j'ai trouvé très peu de conseils pour implémenter le référentiel, l'unité de travail et l'entité Framework sur des modèles complexes et des applications métier réalistes.

Réponses:


6

Tout d'abord, vous traverserez chaque entité que vous avez et vous vous demanderez:

Est-il logique de persister cette entité seule?

Ce que je veux dire ici, c'est que dans votre modèle d'objet, certaines entités sont probablement contenues dans d'autres dans une relation maître-détail. Si votre entité dépend fortement d'une autre, ne créez pas de référentiel pour cette entité uniquement car elle ne sera probablement pas persistante par elle-même. Au lieu de cela, vous créerez un référentiel pour chaque classe parent et vous vous assurerez que les entités enfants et les autres relations sont conservées en même temps.

Je n'aime pas la façon dont ils ont implémenté le modèle UnitOfWork dans le lien que vous avez fourni. Je vous suggère de faire quelque chose de plus dans ce sens . Vous n'avez pas besoin de définir une classe par référentiel. La même classe peut être utilisée pour chaque référentiel, chacun ayant sa propre instance de la classe UnitOfWork pour la durée de vie de l'opération. Vous pouvez également réutiliser le même UnitOfWork dans différents référentiels pour les modifications que vous souhaitez conserver en même temps.


Joli lien! Je vérifie.
Eric Falsken

Votre lien (et votre réponse) ont été les plus utiles même si j'ai fini par ne pas utiliser les modèles fournis. J'ai fini par utiliser une classe wrapper qui a mandaté les méthodes Add / Attach / Remove / SaveChanges pour fonctionner comme un référentiel générique, puis j'ai ajouté une méthode Query / QuerySingle / QueryAll qui accepte des classes de requête personnalisées pour contenir mon implémentation de requête. Cela fonctionne bien pour que je puisse faire des requêtes LINQ et T-SQL sans impliquer directement EF.
Eric Falsken

Entity Framework, avec son utilisation des transactions, est déjà une implémentation du modèle d'unité de travail.
Greg Burghardt

1
lien est mort ...
Newtopian

3

Vous devriez peut-être jeter un œil à la conception pilotée par domaine . Il recommande de regrouper vos objets dans des agrégats et de créer des référentiels uniquement pour l'entité racine de chaque agrégat. C'est une belle façon de mettre de l'ordre dans un grand modèle d'objet complexe.

Vos différents domaines fonctionnels pourraient être des contextes délimités . Il existe différentes techniques pour gérer les contextes délimités qui se chevauchent si la séparation entre eux n'est pas claire.


0

Quel fondement théorique avez-vous trouvé pour la conception de la base de données "Modèle de référentiel"? Je suppose que non. C'est une couche de complexité reposant sur une prémisse bidon: que la "couche de persistance" est quelque chose dont vous devez être isolé. D'après ce que je peux en dire, cela joue sur l'ignorance généralisée de la programmation des principes de conception relationnelle, et sur une centralité présupposée de la conception OO de l'application. Mais il ne justifie pas son existence pour des raisons rationnelles, et encore moins théoriques.

Le One True Path to design de base de données n'a pas changé depuis 30 ans: analysez les données. Trouvez les clés, les contraintes et les relations plusieurs-à-un. Concevez vos tables selon la forme normale de Boyce-Codd. Utilisez des vues et des procédures stockées pour faciliter l'accès aux données.

Si peu aimé qu'il soit, un SGBD SQL fournit une meilleure couche d'isolation que tout ce que le programmeur peut fournir. Il est vrai que lorsque la base de données change, le SQL utilisé pour y accéder peut devoir changer. Mais notez que cela est vrai, qu'il y ait ou non une couche de médiation . Tant que l'application utilise des vues et des procédures stockées pour accéder au SGBD, les outils d'ingénierie SQL ordinaires indiquent quand les modifications apportées à la base de données sous-jacente invalident ces vues et procédures stockées.

C'est là que réside le défi, bien sûr. Une couche de médiation donne l'illusion de l'isolement et le confort au programmeur de l'écriture de code, qu'il sait faire. Apprendre la conception de bases de données et SQL nécessite d'apprendre quelque chose de nouveau. La plupart des gens préfèrent mourir que de penser, et beaucoup réussissent.

Un membre de votre équipe objectera sans doute que l'écriture de SQL pour prendre en charge vos 200 classes représente beaucoup de travail. Sans aucun doute. Mais au moins, c'est un travail utile . Si vous concevez une base de données en imitant votre conception OO, vous ferez également beaucoup de travail, en grande partie inutile, et vaincrez la plupart de ce que le SGBD vous offre.

Par exemple, vous envisagez de refléter l'unité de travail dans la base de données (sous forme de table ou de tables, je présume). Unité de travail est un service intégré du SGBD: begin transaction... base de données de mise à jour ... commit transaction. Rien à modéliser, à part le mappage de vos classes aux tables de base de données en SQL.

Votre question a été publiée il y a 4 ans. Je réponds parce qu'il a été "mis à jour" d'une manière ou d'une autre récemment, ce qui indique que cela intéresse toujours quelqu'un. J'espère que ma réponse encourage le lecteur à appliquer la théorie relationnelle de base au problème au lieu d'adopter une solution de contournement inutile.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.