Est-ce une mauvaise conception? Comment peut-il être amélioré?

9

J'ai écrit ce qui suit il y a quelque temps, mais je suis venu le revoir récemment, et je ne pense pas que ce soit un bon design.

La conception est pour une sorte de couche de base de données modulaire utilisant Entity Framework 4. Il existe un seul objet de base de données qui charge (paresseusement) les contextes de structure d'entité à partir de bibliothèques externes dans un emplacement spécifié, et les instances des contextes chargés sont stockées dans une table de hachage contre leur nom (EG "ContentMgmtContext").

Tout contact avec la base de données dans ce système se fait par le biais de procédures stockées. Pour appeler la base de données, la signature de la méthode de requête ressemble à ceci:

List<TReturn> Query<TReturn>(string Context, 
                             string Procedure, 
                             TransactionScope Scope, 
                             List<ObjectParameter> QueryParameters)

Cette modularité est quelque chose que j'aime. Cependant, cette approche présente un inconvénient majeur: when using the database layer, the code using it has to have a reference to the library in which the context is stored, in order to access the types returned by the stored procedures through Entity Framework.dans le modèle, les objets de la couche de base de données sont convertis en nouveaux objets que la vue et le contrôleur utilisent.

Je pense que c'est une mauvaise conception, mais comment puis-je l'améliorer? J'ai envisagé d'ajouter une interface vide comme IStoredProecedureObjectpour donner à chaque type de données retourné par une procédure stockée un type de base commun, mais cela semble être déjoué par Entity Framework. Chaque fois que le .edmxfichier est recompilé, le code est généré à nouveau et tous les ajouts supprimés. Y a-t-il un moyen d'arrêter cela?

Comment puis-je améliorer cette conception? Quel (autre) problème? Ou suis-je sur la bonne voie?

Andy Hunt
la source

Réponses:

6

Avertissement: je n'utilise pas le cadre d'entité et je suis fortement biaisé contre à peu près n'importe quel cadre d'aide de base de données.

Il semble que vous ayez fait un emballage.

Je fais une distinction entre "wrapper" et "layer". La couche étant quelque chose que vous pourriez compiler dans sa propre DLL / projet / Jar / peu importe. La couche d'accès aux données. Wrapper étant une classe "d'assistance" que vous utilisez dans cette DLL. Dans le but de simplifier l'interface, ou peut-être d'éliminer la duplication.

Le problème avec la simplification de l'interface d'accès à la base de données est que ce n'est généralement pas simple. Soit vous finissez par dupliquer l'interface d'ADO / JDBC / etc. Ou vous forcez les gens à le contourner. Les emballages ont tendance à faire toutes sortes de choses indésirables. Ils peuvent automatiquement fermer une connexion lorsque vous en avez besoin pour prendre en charge une transaction. Ils laissent souvent par erreur des connexions ouvertes si vous deviez diffuser des données et utilisent l'une de ces langues récupérées. Pour donner toute la puissance de la bibliothèque derrière votre wrapper, vous êtes obligé de la dupliquer.

Des bibliothèques comme ADO / JDBC sont déjà une GRANDE interface. Ce sont quelques-uns des meilleurs exemples de POO bien faits. Je préférerais les utiliser sur un emballage de wizbang sorti de son chapeau.

L'interface classique de style JDBC / ADO est bien connue et comprise. L'emballage que vous avez sorti de votre chapeau ne l'est pas.

Vous voulez réduire les «paramètres.Add» redondants? Examinez les génériques. Ou acceptez simplement qu'en essayant de réduire "paramter.Add", vous poussez simplement le ".add" vers une autre couche de code.

BTW c'est une grande question. Je le voterais 10 fois si je le pouvais.

Edit: Bien sûr, le code JDBC serait caché dans la couche d'accès aux données.

Lord Tydus
la source
Je suis d'accord, avec le recul, que c'est plus un enroulement autour d'EF 4 que lui-même. L'idée sous-jacente était de permettre la réutilisation de différents éléments de connectivité de base de données (comme un modèle de données standard) tout en ayant un point d'entrée unique pour plusieurs bases de données, chacune avec la caractéristique de réutilisation. Ce wrapper de base de données est compilé dans une bibliothèque distincte (avec une autre logique métier). Comment suggéreriez-vous que je modifie ma conception pour l'améliorer?
Andy Hunt du
+1 pour l'excellent contenu malgré votre biais EF ... bien qu'EF soit plus qu'un framework d'assistance DB. Vous avez raison lorsqu'il essaie de fabriquer un emballage pour cela.
SoylentGray,